我的应用程序将 QTabWidget 用于多个“页面”,其中顶级菜单根据用户所在的页面而变化。
我的问题是尝试重新创建菜单栏的内容会导致主要的显示问题。它在除 Mac OS X 之外的所有平台上按预期使用第一种和第三种样式(尚未测试第二种,但我宁愿不使用该样式)。
第一个菜单是按照我在应用程序中创建的大多数方式创建的,它们会收到正确的标题,但是一旦重新创建菜单就消失了。
第二个菜单出现在菜单栏的初始填充和重新填充中,但在这两种情况下都带有“无标题”标签。第二个菜单的样式仅在尝试解决此问题时创建,因此这是我能够保留菜单的唯一方法。
第三个动态菜单永远不会出现,句号。我使用这种样式来动态填充即将显示的菜单。
我曾尝试删除 QMenuBar 并重新创建一个
m_menuBar = new QMenuBar(0);
并使用它而不是
m_menuBar->clear()
但它具有相同的行为。我没有足够的声誉来发布图像内联,所以我将包括 imgur 链接:
启动行为:ojit_a
发布按钮点击行为:http://i.imgur.com/ZEvvGKl.png
我创建了一个最小示例来在带有 Qt 5.3 的 Mac OS X 10.9.4 上重现此行为。
主窗口.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");
}
主窗口.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
最佳答案
所有这些看起来都像是 OS X 上的 Qt 错误。实际上,这是一个非常古老的错误。
您可以通过 QMenuBar::addMenu 函数调用来解决问题并且不使用 QMenu,就像您在此处所做的那样:m_menuBar->addMenu("One");
而不是通过动态创建 QMenu 实例,然后为 QMenu::menuAction 检索的 QAction 实例调用 QMenuBar::addAction 从 QMenu 检索的 QAction 使用,如下所示:
m_menuBar->addAction(oneMenu->menuAction());
除了 QMenuBar::addAction 之外,如果您只想动态创建某些特定菜单项,您可以使用 QMenuBar::removeAction 和 QMenuBar::insertAction 。
根据您在此处的源代码,它的修改版本处理每次单击按钮时的所有菜单动态创建(您在源代码中执行此操作),并且每次单击按钮时,菜单“动态”都会填充不同数量的项目.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private slots:
void changeMenuBar();
private:
QMenuBar *m_menuBar;
QMenu *m_dynamicMenu;
int m_clickCounter;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
m_clickCounter(1)
{
m_menuBar = new QMenuBar(this);
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_clickCounter;
m_menuBar->clear();
QMenu *oneMenu = new QMenu("One");
oneMenu->addAction("bar1");
oneMenu->addAction("baz1");
m_menuBar->addAction(oneMenu->menuAction());
QMenu *twoMenu = new QMenu("Two");
twoMenu->addAction("foo2");
twoMenu->addAction("bar2");
twoMenu->addAction("baz2");
m_menuBar->addAction(twoMenu->menuAction());
m_dynamicMenu = new QMenu("Dynamic");
for (int i = 0; i < m_clickCounter; ++i) {
m_dynamicMenu->addAction(QString("foo%1").arg(i));
}
m_menuBar->addAction(m_dynamicMenu->menuAction());
}
此外,在为 OS X 开发菜单逻辑时,最好记住:
关于c++ - Qt:在 Mac OS X 上更改应用程序 QMenuBar 内容,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26004830/