QMenu中的非交互式项目

7
我是一名有用的助手,以下是您需要翻译的内容:

我正在尝试在QT中构建一个具有一些非交互式项目的菜单。 我在MyCustomMenuClass中对QMenu进行了子类化。 我正在尝试向我的菜单添加节标题,以便用户更清楚地了解。

例如,它应该像这样:

My section 1 title
Action 1
Action 2
Action 3
My second section title
Action 4
Action 5

问题在于部分标题始终会对鼠标作出反应,但我希望它们不会对鼠标悬停作出反应,使其更美观。有什么好的想法吗?
5个回答

12

从QMenu文档中得知:

有四种类型的操作项:分隔符、显示子菜单的操作项、小部件和执行操作的操作项。使用addSeparator()插入分隔符,使用addMenu()插入子菜单,所有其他项目都被视为操作项。

这让人想起了什么:小部件!你可以将小部件添加到菜单中?这意味着你已经解决了问题,可以做任何想做的事情。

你所需要的是一个QWidgetAction对象。它允许您将自定义小部件插入为操作项。您的标题将成为自定义小部件。如果您只需要一个标题,则QLabel就足够了:

QMenu* myMenu = new QMenu(...);
QLabel* label = new QLabel(tr("<b>Title</b>"), this);
label->setAlignment(Qt::AlignCenter);

QWidgetAction* a = new QWidgetAction(myMenu);
a->setDefaultWidget(label);

-- 此代码的源

查看此相关问题以获取更复杂的示例代码:在QtCreator中向QMenu添加Widget有什么方法


请注意,这种技术在MacOS/X的本地菜单栏中不起作用,因为MacOS/X不知道如何渲染Qt小部件。 - Jeremy Friesner

5
对于Qt 5.1及以上版本,您应该使用addSection(const QString &)。它专为您尝试的内容设计而成。如果您不仔细匹配字体和间距等,基于小部件的解决方案看起来会很奇怪。
对于Qt 4,如果您真的打算让您的代码在Qt 4中编译,则应将addAction(const QString &)用作备选方案。我认为这是一个合理的权衡。
对于Qt 5.0 - 嗯,您根本不应再使用它了,就是这么简单 :)

1
我尝试过这个,但在Win7上,这些部分显示为普通分隔符。还有其他人遇到这个问题吗? - Martin Hennings
@Martin 这是一个bug。如果还没有为此报告bug,请随时报告。 - Kuba hasn't forgotten Monica
看起来Windows样式不支持带有文本的分隔符。通过添加命令行选项“-style fusion”使用Qt5.1融合样式,分隔符文本是可见的。 - Martin Hennings
@Martin 这仍然是一个bug :) 没有太多与Windows相关的内容,只是样式代码缺少一个功能,Qt在这方面并不依赖于Windows本身。如果没有关于它的错误报告,我建议您提交一个,至少它将允许识别缺失的功能。 - Kuba hasn't forgotten Monica
请参阅Qt5.1.1,qwindowsvistastyle.cpp,第1278行:分隔符不带文本装饰(这将在第1354行及以下绘制),这似乎是设计上的。 - Martin Hennings
@Martin 更多的是因为疏忽或时间不够 :) - Kuba hasn't forgotten Monica

1

如果想要一个弹出菜单,你可以创建自定义的QWidgetAction并添加到弹出菜单中。

下面是一个QWidgetAction示例:

#include <QWidgetAction>

class  myCustomWidgetAction: public QWidgetAction
{
    Q_OBJECT
public:
    explicit myCustomWidgetAction(QWidget * parent);

protected:
    QWidget * createWidget(QWidget *parent);

};


myCustomWidgetAction::myCustomWidgetAction(QWidget * parent):QWidgetAction(parent) {
}
QWidget * myCustomWidgetAction::createWidget(QWidget *parent){
    myCustomWidget * widget=new myCustomWidget(parent);
    return widget;
}

您可以将小部件添加到工具按钮中,以便在弹出菜单中显示:
myCustomWidgetAction * widgetAction   = new myCustomWidgetAction(this);

ui->toolButton->addAction(widgetAction);

您的自定义小部件可以是包含不同元素的列表,也可以是任何其他小部件。您还可以将多个myCustomWidgetAction实例添加到toolButton中。
您还可以将其添加到QMenu中,例如:
QMenu* menu = new QMenu();

menu->addAction(widgetAction);

0

我刚刚用一个相当简单的策略解决了同样的问题,在我的情况下已经足够好了:

QMenu* menu = new QMenu();
act = menu->addAction("My section 1 title:");
act->setEnabled(false);
// add Action 1
// add Action 2
// add Action 3

act = menu->addAction("My second section title:");
act->setEnabled(false);
// add Action 4
// add Action 5


0
这里有一个可行的选项 - 将操作设置为禁用,然后与选择QMenu :: item:disabled的样式表相结合。
例如,从一些工作代码中:
   self.teamTabsMoreMenu.addAction('Hidden team tabs').setEnabled(False)
   self.teamTabsMoreMenu.addAction('Select a team to unhide:').setEnabled(False)
   self.teamTabsMoreMenu.addSeparator()
   for extTeamName in self.hiddenTeamTabsList:
      self.teamTabsMoreMenu.addAction(extTeamName)
   self.teamTabsMoreMenu.setStyleSheet('QMenu::item:disabled{background-color:rgb(220,220,220);color:black;font-weight:bold}')

上面的样式还意味着“标题”部分在悬停时不会改变字体颜色或背景颜色,这对于标题来说非常好。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接