How to attach a top-down bar to the bottom of a menu in QMainWindow

When you save a file on a Mac, the panel seems to go down from the top panel really cool. I want to create a class that does a similar thing using the Qt framework. There are a few things that I'm confused about:

  • When the panel goes down, the entrance to the parent window should be blocked. This is easy with QDialog, since it has a setModal () method, however QDialogs, by default pop-out. I am not sure how to get around this.

  • A new instance of the DescendingPanel QMenua class is created in QMainProject. How would you do this, assuming there are other widgets under the menu bar. DescendingPanel should appear above them.

I would really appreciate any help with this.

EDIT

I had the idea that instead of attaching a dialog box under the menu bar, just make it appear under it and delete the window frame. Thus, it would create the illusion that he jumped out from under it. Of course, Move events should also be handled in such a way that Dialog is always under the menu bar, but for a later one. Here, the code I used to get the DescendingDialog will appear on the menu bar.

class DescendingDialog : public QWidget { QMainWindow* Window; QWidget* Menu; QPoint GlobalLocationOfMenu; int DialogWidth; int DialogHeight; int X() { int XDistanceOfPanel = GlobalLocationOfMenu.x() + ((Menu->width()/2) - (this->DialogWidth/2)); //GlobalLocationOfMenu.x() returns 0; return XDistanceOfPanel; } int Y() { int YDistanceOfPanel = GlobalLocationOfMenu.y()+Menu->height(); //GlobalLocationOfMenu.y() returns 0; return YDistanceOfPanel; } void SetGeometry() { this->setGeometry(this->X(),this->Y(),this->DialogWidth,this->DialogHeight); } public: DescendingDialog(QMainWindow* Window,int DialogWidth,int DialogHeight):QWidget(NULL) { this->Window = Window; this->Menu = this->Window->menuWidget(); this->DialogWidth = DialogWidth; this->DialogHeight = DialogHeight; QPoint RelativeLocationOfMenu = this->Menu->pos(); this->GlobalLocationOfMenu = QWidget::mapToGlobal(RelativeLocationOfMenu); this->SetGeometry(); } }; 

This did not work because GlobalLocationOfMenu.x () and .y () returned 0, so the dialog does not appear where I want.

+6
source share
1 answer

You can enable the dialog β€œslide” with a function like this:

 #include <QDialog> #include <QPropertyAnimation> #include <QParallelAnimationGroup> void makeAppear(QDialog * dialog, QRect geometryEnd) { static QParallelAnimationGroup *animationGroup = 0; if (animationGroup) { for(int i = 0, ie = animationGroup->animationCount(); i != ie; ++i) delete animationGroup->animationAt(i); delete animationGroup; } // Set up start and end geometry for 'dialog'. QPoint parentTopLeft = dialog->parentWidget()->geometry().topLeft(); geometryEnd.translate(dialog->parentWidget()->mapToGlobal(parentTopLeft)); QRect geometryBegin = geometryEnd; geometryBegin.setHeight(0); // Set up start and end geometry for the only child widget of 'dialog'. QWidget * dialogChildWidget = dynamic_cast< QWidget * >(dialog->children().first()); if ( !dialogChildWidget ) return; QRect childGeometryEnd = dialogChildWidget->geometry(); QRect childGeometryBegin = childGeometryEnd; childGeometryBegin.translate(0, geometryEnd.height() * (-1)); // Set up animation for 'dialog'. QPropertyAnimation *dialogAnimation = new QPropertyAnimation(dialog, "geometry"); dialogAnimation->setDuration(400); dialogAnimation->setStartValue(geometryBegin); dialogAnimation->setEndValue(geometryEnd); // Set up animation for the only child widget of 'dialog'. QPropertyAnimation *childAnimation = new QPropertyAnimation(dialogChildWidget, "geometry"); childAnimation->setDuration(400); childAnimation->setStartValue(childGeometryBegin); childAnimation->setEndValue(childGeometryEnd); // Set up (and start) a parallel animation group animationGroup = new QParallelAnimationGroup; animationGroup->addAnimation(dialogAnimation); animationGroup->addAnimation(childAnimation); animationGroup->start(); // Make 'dialog' visible, borderless, modal. dialog->setModal(true); dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); dialog->show(); } 

The dialog argument should point to an instance (hidden / not visible) of QDialog with one child widget that contains all the other widgets that belong to the dialog.

The geometryEnd argument must indicate the location and size of the dialog after it appears (relative to its parent widget).

The result looks like this .

+2
source

Source: https://habr.com/ru/post/904018/


All Articles