Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

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

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

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top