Non interactive items in QMenu
Asked Answered
R

5

7

I'm trying to build a menu with some items that are not interactive in QT. I subclass QMenu in my MyCustomMenuClass. I'm trying to add section titles to my menu so that it's clearer for the user.

For example, it should look like this:

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

The issue is that the section titles always react to the mouse, but I would like them to not react to a mouse over so that it would be prettier. Any idea on how to do it?

Radome answered 25/3, 2014 at 13:21 Comment(0)
D
12

From the QMenu documentation:

There are four kinds of action items: separators, actions that show a submenu, widgets, and actions that perform an action. Separators are inserted with addSeparator(), submenus with addMenu(), and all other items are considered action items.

This rings a bell: Widgets! You can add a widget to the menu? That means you are settled, you can do whatever you want.

What you need is a QWidgetAction object. It allows you to insert a custom widget as an action. Your titles will be custom widgets. If you only need a title, a QLabel should suffice:

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

-- Source for this code

See this related question for more sophisticated example code: Is there a way to add a Widget to a QMenu in QtCreator

Delay answered 25/3, 2014 at 13:29 Comment(1)
Note that this technique won't work in MacOS/X's native menu bar, since MacOS/X doesn't know how to render Qt widgets.Chitterlings
R
5

For Qt 5.1 and up, you should be using addSection(const QString &). It's designed precisely for what you're trying to do. The widget-based solutions will look weird unless you take great care at matching the fonts and spacing etc.

For Qt 4, you should use addAction(const QString &) as a fallback, if you really intend your code to compile with Qt 4. It's a reasonable tradeoff, I think.

For Qt 5.0 - well, you shouldn't be using it at all anymore, it's as simple as that :)

Romilly answered 25/3, 2014 at 22:1 Comment(6)
I tried this, but the sections show as plain separators on Win7. Someone else have this problem?Tedric
@Martin It's a bug. Feel free to report it if there's no bug for it yet.Organza
It looks like Windows style doesn't support separators with text. Using Qt5.1 fusion style (by adding command line option -style fusion) the separator texts are visible.Tedric
@Martin It's still a bug :) There's not much Windows-specific there, it's just the style code missing a feature, Qt is not dependent on Windows itself in this regard. If there's no bug report for it, I suggest you file one, at least it'll allow recognition of a missing feature.Organza
See Qt5.1.1, qwindowsvistastyle.cpp, l.1278: Separators are not decorated with text (which would be drawn l.1354ff), and that seems to be by design.Tedric
@Martin More by omission or lack of time :)Organza
T
1

For a popup menu you can create your custom QWidgetAction to add to a popup menu.

This is sample 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;
}

You can then add your widget to a toolButton to be diaplayed in a popup menu:

myCustomWidgetAction * widgetAction   = new myCustomWidgetAction(this);

ui->toolButton->addAction(widgetAction);

Your custom widget can be a list containing different elements or it can be any other widget. You can also add multiple instances of myCustomWidgetAction to the toolButton.

You can also add it to a QMenu like:

QMenu* menu = new QMenu();

menu->addAction(widgetAction);
Tucket answered 25/3, 2014 at 14:22 Comment(0)
B
0

I just solved the same issue with this rather simple strategy, which was good enough in my case:

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

Blether answered 19/1, 2021 at 19:45 Comment(0)
P
0

Here's an option that works - set the actions to disabled as above, then combine with a styleSheet that selects QMenu::item:disabled

e.g. from some working code:

   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}')

The style above also means the 'header' section doesn't change font color or background color on hover, which is nice for a header.

enter image description here

Posology answered 29/10, 2022 at 3:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.