Как прикрепить «нисходящую панель» к нижней части меню в QMainWindow - PullRequest
6 голосов
/ 18 декабря 2011

Когда вы сохраняете файл на Mac, панель как бы спускается с верхней панели очень круто. Я хочу создать класс, который делает похожую вещь, используя фреймворк Qt. Я запутался в нескольких вещах:

  1. Когда панель опускается, ввод в родительское окно должен быть заблокирован. Это легко сделать с QDialog, так как он имеет метод setModal (), однако - QDialogs, по умолчанию всплывающее окно. Я не уверен, как обойти это.

  2. В QMainProject существует QMenua, создается новый экземпляр класса DescendingPanel. Как бы вы это сделали, если предположить, что есть другие виджеты под меню. Над ними должна появиться DescendingPanel.

Я был бы очень признателен за любую помощь в этом.

EDIT

У меня была идея, что вместо того, чтобы привязывать диалог под меню, просто сделайте так, чтобы он появился под ним, и удалите оконную раму. Таким образом, это создаст иллюзию, что он выскочит из-под ног. Конечно, события Move также должны обрабатываться так, чтобы диалог всегда был под строкой меню, но это на потом. Вот код, который я использовал для отображения DescendingDialog под строкой меню.

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();

    }
};

Это не сработало, потому что GlobalLocationOfMenu.x () и .y () вернули 0, поэтому диалоговое окно не появляется там, где я хочу.

1 Ответ

2 голосов
/ 24 декабря 2011

Вы можете позволить диалогу «скользить», используя функцию, подобную этой:

#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();
}

Аргумент dialog должен указывать на (скрытый / не видимый) экземпляр QDialog с одним единственным дочерним виджетом, который содержит все другие виджеты, принадлежащие диалогу.

Аргумент geometryEnd должен указывать позицию и размер dialog после его появления (относительно родительского виджета).

Результат выглядит следующим образом .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...