我的应用程序使用QTabWidget来实现多个“页面”,顶部菜单栏根据用户所在的页面而变化。
我的问题是,尝试重新创建菜单栏的内容会导致严重的显示问题。在除了Mac OS X以外的所有平台上,第一种和第三种样式都按预期工作(没有测试第二种,但我宁愿不使用那种样式)。
第一个菜单是我在应用程序中创建大多数菜单的方式,它们接收到正确的标题,但是一旦重新创建菜单,它们就会消失。
第二个菜单在初始填充和重新填充菜单栏时都会出现,但在两种情况下都有标签“未命名”。第二个菜单的样式是在尝试解决这个问题时创建的,所以这是我能让菜单保持存在的唯一方法。
第三个动态菜单从未出现过。我使用这种样式来动态填充即将显示的菜单。
我已经尝试删除QMenuBar并使用以下代码重新创建:
m_menuBar = new QMenuBar(0);
相比于m_menuBar->clear()
,使用它具有相同的行为。
我没有足够的声望来内联发布图片,因此我将包含imgur链接:
启动行为:http://i.imgur.com/ZEvvGKl.png
发布按钮点击后的行为:http://i.imgur.com/NzRmcYg.png
我已经创建了一个最小化的示例,在Mac OS X 10.9.4和Qt 5.3上重现了这种行为。
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_menuBar = new QMenuBar(0);
m_dynamicMenu = new QMenu("Dynamic");
connect(m_dynamicMenu, SIGNAL(aboutToShow()), this, SLOT(updateDynamicMenu()));
changeMenuBar();
QPushButton *menuBtn = new QPushButton("Test");
connect(menuBtn, SIGNAL(clicked()), this, SLOT(changeMenuBar()));
setCentralWidget(menuBtn);
}
void MainWindow::changeMenuBar() {
m_menuBar->clear();
// Disappears as soon as this is called a second time
QMenu *oneMenu = m_menuBar->addMenu("One");
oneMenu->addAction("foo1");
oneMenu->addAction("bar1");
oneMenu->addAction("baz1");
// Stays around but has 'Untitled' for title in menu bar
QMenu *twoMenu = new QMenu("Two");
twoMenu->addAction("foo2");
twoMenu->addAction("bar2");
twoMenu->addAction("baz2");
QAction *twoMenuAction = m_menuBar->addAction("Two");
twoMenuAction->setMenu(twoMenu);
// Never shows up
m_menuBar->addMenu(m_dynamicMenu);
}
void MainWindow::updateDynamicMenu() {
m_dynamicMenu->clear();
m_dynamicMenu->addAction("foo3");
m_dynamicMenu->addAction("bar3");
m_dynamicMenu->addAction("baz3");
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private slots:
void changeMenuBar();
void updateDynamicMenu();
private:
QMenuBar *m_menuBar;
QMenu *m_dynamicMenu;
};
#endif // MAINWINDOW_H
oneMenu->menuAction()
是正确的,并且对前两个菜单有效,但显然(在Mac OS X上)当将菜单添加到QMenuBar
时,必须具有现有操作。由于我的动态菜单示例直到发出aboutToShow()
信号才添加操作,因此我的解决方法是使用一个没有其他作用的QAction
填充动态菜单以使其最初显示。在我的updateDynamicMenu()
槽中,我清除并重新填充动态菜单。 - syriusaboutToShow()
信号的槽中填充菜单。我只是提到,在您的动态菜单示例中,如果直到发出aboutToShow()
信号才填充它,它将永远不会出现在菜单栏中,这就是我发布初始评论并要求一个空的QAction(因为您还不知道内容)的原因。我认为将此包含在答案中对其他人会有所帮助。 - syrius