如何安装“下降面板”到 QMainWindow 中菜单栏的底部

发布于 2024-12-22 03:47:24 字数 1805 浏览 0 评论 0原文

当您在 Mac 上保存文件时,一个面板会以一种非常酷的方式从顶部栏下降。我想创建一个使用 Qt 框架执行类似操作的类。有很多事情让我感到困惑:

  1. 当面板下降时,父窗口的输入应该被阻止。这对于 QDialog 来说很容易,因为它有 setModal() 方法,但是 - QDialogs,默认情况下会弹出。我不知道如何解决这个问题。

  2. 在 QMainProject 中,创建了 DescendingPanel 类的 QMenua 新实例。假设菜单栏下方还有其他小部件,您会如何做到这一点。 DescendingPanel 应出现在它们上方。

我真的很感激任何帮助。

编辑

我有一个想法,不要将对话框固定在菜单栏下,而是让它出现在菜单栏下方并删除窗口框架。这样一来,就会给人一种从下面钻出来的错觉。当然,还必须处理移动事件,以便对话框始终位于菜单栏下方,但这是稍后的事。这是我用来让 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,因此对话框不会出现在我想要的位置。

When you save a file on a Mac, a panel kinda descends down from the top bar in a really cool way. I want to create a class that does a similar thing using the Qt framework. There are a number of things that I'm confused about:

  1. When the panel descends, input to the parent window should be blocked. This is easy with QDialog as it has the setModal() method, however - QDialogs, by default pop-out. I'm not sure how to get around this.

  2. In a QMainProject, there is a QMenua new instance of the DescendingPanel class is created. How would you do that, supposing there are other widgets below the menubar. The DescendingPanel should appear above them.

I would really appreciate any help with this.

EDIT

I had an idea that instead of pegging the dialog under the menubar, just make it appear under there and remove the window frame. That way, it would give an illusion that it popped out from under there. Ofcourse, Move events would also have to be handled so that the Dialog is always under the menubar but that's for later. Here's the code I used to get the DescendingDialog to appear under the menubar.

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

    }
};

It didn't work because the GlobalLocationOfMenu.x() and .y() returned 0 so the dialog doesn't appear where I want it to.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

椵侞 2024-12-29 03:47:24

您可以使用类似于以下的函数让对话框“滑入”:

#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 出现后的位置和大小(相对于其父窗口小部件)。

结果看起来像这样

You can let a dialog "slide in" by using a function similar to that:

#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 shall point to a (hidden/not visible) QDialog instance with one single child widget, that contains all other widgets that belong to the dialog.

The geometryEnd argument shall specify position and size of dialog after it has appeared (relative to it's parent widget).

The result looks like this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文