qtqmenubar

Qt stylesheet : set a specific QMenuBar::item background color


I have a QMenuBar with for example two QMenu items.

enter image description here

How can I only make the "Floors" item be blue, for example? I know how to change it for ALL the items with:

QMenuBar::item {
     background: ...;
}

But I can't find a way to color a specific item. I tried to use setProperty on Qmenu, I tried with setPalette,... I just find nothing working. Is there a way to set a specific QMenuBar::item property in C++ code?


Solution

  • I finally found something.

    1. Create your own object, for example WidgetMenuBar, inherited from QMenuBar.

    2. Add a property to identify wich item should be colored differently:

      for (int i = 0; i < this->actions().size(); i++){
          actions().at(i)->setProperty("selection",false);
      }
      // Only the first item colored
      actions().at(0)->setProperty("selection",true);
      
    3. Reimplement void paintEvent(QPaintEvent *e) function of your widget:

      void WidgetMenuBarMapEditor::paintEvent(QPaintEvent *e){
          QPainter p(this);
          QRegion emptyArea(rect());
      
          // Draw the items
          for (int i = 0; i < actions().size(); ++i) {
              QAction *action = actions().at(i);
              QRect adjustedActionRect = this->actionGeometry(action);
      
              // Fill by the magic color the selected item
              if (action->property("selection") == true)
                  p.fillRect(adjustedActionRect, QColor(255,0,0));
      
              // Draw all the other stuff (text, special background..)
              if (adjustedActionRect.isEmpty() || !action->isVisible())
                  continue;
              if(!e->rect().intersects(adjustedActionRect))
                  continue;
              emptyArea -= adjustedActionRect;
              QStyleOptionMenuItem opt;
              initStyleOption(&opt, action);
              opt.rect = adjustedActionRect;
              style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p, this);
          }
      }
      

    You can see here how to implement paintEvent function.