改变 QMenu 中子菜单的位置

Change position of submenus in a QMenu

在我的项目中,我有一个带有子菜单项的 QMenu。子菜单项比较多所以高度比较大

我想使子菜单相对于执行子菜单的项目垂直居中。

我已经对要重新定位的子菜单进行了子类化,并尝试更改 "aboutToShow" 上的几何形状只是为了测试,但这没有效果:

class MySubMenu : public QMenu
{
    Q_OBJECT
public:
    QuickMod();
    ~QuickMod();

private slots:
    void centerMenu();
};



MySubMenu::MySubMenu()
{
    connect(this, SIGNAL(aboutToShow()), this, SLOT(centerMenu()));
}

MySubMenu::~MySubMenu()
{
}

void MySubMenu::centerMenu()
{
    qDebug() << x() << y() << width() << height();
    setGeometry(x(), y()-(height()/2), width(), height());
}

这是我用 MS 快速绘制的一张图片,我希望它能从视觉上解释我想要实现的目标:(之前和之后)

感谢您的宝贵时间!

aboutToShow 在几何图形更新之前发出,以便稍后覆盖更改。解决办法是在显示后立即改变位置,为此我们可以使用一个 QTimer 和一个小时间。

示例:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QTimer>

class CenterMenu: public QMenu{
    Q_OBJECT
public:
    CenterMenu(QWidget *parent = Q_NULLPTR):QMenu{parent}{
        connect(this, &CenterMenu::aboutToShow, this, &CenterMenu::centerMenu);
    }
    CenterMenu(const QString &title, QWidget *parent = Q_NULLPTR): QMenu{title, parent}{
        connect(this, &CenterMenu::aboutToShow, this, &CenterMenu::centerMenu);
    }
private slots:
    void centerMenu(){
        QTimer::singleShot(0, [this](){
            move(pos() + QPoint(0, -height()/2));
        });
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;

    auto fileMenu = new QMenu("Menu1");
    w.menuBar()->addMenu(fileMenu);
    fileMenu->addAction("action1");
    fileMenu->addAction("action2");
    auto children_menu = new CenterMenu("children menu");
    children_menu->addAction("action1");
    children_menu->addAction("action2");
    children_menu->addAction("action3");
    children_menu->addAction("action4");
    children_menu->addAction("action5");
    children_menu->addAction("action6");
    fileMenu->addMenu(children_menu);
    w.show();
    return a.exec();
}

#include "main.moc"