一个menu的样式是由其上边的菜单项决定的,所以要个性化定制菜单,其实就是要个性化定制各个菜单项。在Qt中菜单项是QAction类,但是如果直接用它的话:其样式是由系统所决定的,我们只能在上边写一些字符或者再加一个Icon.

        但是有时候我们需要定制一个个性化的menu。比如:你的App整体风格为蓝色调,但是在Qt for symbian上系统菜单项却是黑色的,Qt for Windows是灰色的,显然这样就不搭配了,所以这才需要我们去个性化它。

       个性化的最简单方式就是给菜单项上边刷一张图片。欲达到的效果为: 

1:当鼠标hover移动进入该菜单项区域时:其应变成另外一张背景图片。

2:当鼠标hover移出该菜单选项时:其恢复原先的背景图片。

3:当mousePress时:换成另一张图片.

4:当mouseRelease时:换回原先的背景图片,并且隐藏菜单本身。 

       由上分析可知:个性化定制一个菜单项时:至少要准备两张图片,一张用于平时状态,一种用于hover-in和mouse-press状态。

---------------------------------------------------------------------------------------------------------------------------------

       对标准的菜单项控件QAction,由于其并 非继承于QWidget,所以我们无法再上边绘制image。只能调用它自身的函数来摆个icon和写点字符,这显然达不到我们的要求。

       为了实现个性话定制菜单项,Qt提供了另外一个类:QWidgetAction。

亦即:普通的菜单项我们可以用QAction实现.希望个性化定制的菜单项我们是用QWidgetAction来实现。

 

       而它实现个性化定制的方法是:它本身可以充当一个中间“容器”,从而在其上摆一个普通的QWidget,这样显示在用户面前的就是这个其上的widget。对于这个widget而言:我们完全可以自由定制,从而间接表现出对菜单项的定制。


      由上知:我们所谓的个性化定制其实就是在先创建一个指定样式的QWidget对象;而后将其放到QWidgetAction上;最后将创建好的QWidgetAction对象放到菜单面板中!!

------------------------------------------------------------------------------------------------------------------------

      那么:照上边所说,这里还有一个问题需要解决:那就是其上边这个普通widget的parent父亲是谁?我们不可能将其指定为QWidgetAction,毕竟它并不继承于QWidget,无法作为parent。

       其实这个普通窗口的父窗口我们是直接指定为:存放这个菜单项的菜单QMenu。  以为QMenu是继承自QWidget,可以当做parent。

      具体实现上:

       ① :对于QWidgetAction而言,我们要派生重写其成员函数:

             QWidget* createWidget(QWidget*);

              帮助文档上如此解释:

              This function is called whenever the action is added to a container widget   that supports custom widgets 

亦即:当我们将个性化的菜单项加到容器窗口中时就会立即调用该函数。

 

        而该函数的作用就是:把创建好的放于其上的普通widget父窗口设置为该菜单项所在的容器窗口(QMenu);该函数的传入参数就是:这个QWidgetAction的parent ,它是由系统传入的,我们不需要去管它。 

---------------------------------------------------------------------------------------------------------------------------

 

总的主体流程就是:

1:首先派生QWidgetAction,在其内创建一个定制好的普通widget(注意此widget是没有指定父对象的)

2:重写createWidget()函数,将其父窗口指定为该菜单项所在的容器窗口,亦即:传入的指针。 


而后所做的无非是重写一下mouse事件 和hover事件,来实现上边所说的图片变换,这里就不复述了。