QAction Icon Change on Hover

2k views Asked by At

In my project I display a QMenu with several QAction objects. I want the QAction icon to change when the user hovers over it.

Here is my current code:

QPixmap icons(":/icons/platformIcons.png");

QIcon icon;
icon.addPixmap(icons.copy(0, 0, 16, 16), QIcon::Selected, QIcon::On);
icon.addPixmap(icons.copy(0, 16, 16, 16), QIcon::Selected, QIcon::Off);

ui->actionOpen->setIcon(icon);

However the icon doesn't change when the user hovers over the QAction. I've tried modes Normal and Active and the result is the same. If I switch the states, the icon is reversed, but still doesn't change on a hover (or click for that matter).

Thanks for your time.

1

There are 1 answers

3
Romain Pokrzywka On

Support for hovering normal/active icons in menus and toolbars seems to depend on the platform style, and is not supported with native Mac styling in particular, even when disabling usage of the native menu bar (ie. having the menus show at the top of the desktop rather than within the application window).

I've made a quick try with a Qt Designer form on a Mac to replicate your use case (basically ends up as the same C++ code using QIcon::addPixmap()):

?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget"/>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>22</height>
    </rect>
   </property>
   <property name="nativeMenuBar">
    <bool>false</bool>
   </property>
   <widget class="QMenu" name="menuYo">
    <property name="title">
     <string>Yo</string>
    </property>
    <addaction name="actionFoo"/>
    <addaction name="actionBar"/>
   </widget>
   <addaction name="menuYo"/>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="actionFoo"/>
   <addaction name="actionBar"/>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionFoo">
   <property name="checkable">
    <bool>true</bool>
   </property>
   <property name="icon">
    <iconset>
     <normaloff>../red-circle.png</normaloff>
     <normalon>../greeb-circle.png</normalon>
     <activeoff>../red-square.png</activeoff>
     <activeon>../green-square.png</activeon>../red-circle.png</iconset>
   </property>
   <property name="text">
    <string>Foo</string>
   </property>
  </action>
  <action name="actionBar">
   <property name="text">
    <string>Bar</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

When using the default Mac styling, I only get the red/green circle icon in the menu and the toolbar, even when hovering the mouse. However if I force another style with e.g. ui->menuYo->setStyle(QStyleFactory::create("fusion")); then the hovering works, but the menu doesn't look native anymore...