为什么 QToolTips 不会出现在 QMenu 中的 QActions 上



我正在用 GUI 编写一个应用程序 PySide .我在QPushButton上设置了一个QMenu,通过QMenu.addAction添加了几个QActions。为了进一步向用户解释这些操作,我添加了QToolTipQAction.setToolTip

当我现在运行 GUI 时,我的QToolTip不会显示。下面发布的示例重现了相同的问题,有什么想法吗?

提前致谢

import sys
from PySide import QtGui
class Example(QtGui.QPushButton):
    def __init__(self, parent = None):
        super(Example, self).__init__(parent)
        self.setText('TestMenu')
        self.setToolTip('This is a Test Button')
        menu = QtGui.QMenu(self)
        action_1 = menu.addAction('Action1')
        action_1.setToolTip('This is action 1')
        action_2 = menu.addAction('Action2')
        action_2.setToolTip('This is action 2')
        action_3 = menu.addAction('Action3')
        action_3.setToolTip('This is action 3')
        action_4 = menu.addAction('Action4')
        action_4.setToolTip('This is action 4')
        self.setMenu(menu)
        self.show()
def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    app.exec_()
if __name__ == '__main__':
    main()

在Qt-5.1或更高版本中,您只需使用QMenu.setToolTipsVisible,菜单项将按预期显示其工具提示(请参阅QTBUG-13663):

    menu.setToolTipsVisible(True)

但是,对于Qt-4.*和Qt-5.0,情况有所不同。如果将操作添加到工具栏,将显示其工具提示;但是,如果将相同的操作添加到QMenu,则不会,并且没有内置的 API 来更改它。有几种方法可以解决此问题。一种是改用状态提示,这将在状态栏中显示菜单项信息。另一种是使用 QMenu.hovered 信号和 QToolTip.showText 自己实现菜单项工具提示功能:

        self.menu = QtGui.QMenu(self)
        ...
        self.menu.hovered.connect(self.handleMenuHovered)
    def handleMenuHovered(self, action):
        QtGui.QToolTip.showText(
            QtGui.QCursor.pos(), action.toolTip(),
            self.menu, self.menu.actionGeometry(action))
<</div> div class="one_answers">

实际上,您不必执行任何解决方法来显示工具提示,从Qt 5.1开始,您可以使用QMenu的属性toolTipsVisible,默认情况下设置为false

请参阅相关的 Qt 建议。

在 ekhumoro 的帮助下,我得到了这个解决方案。这可能不是最漂亮的东西,下面的代码将菜单和工具提示定位得有些不清晰,但在我的实际程序中,它看起来非常整洁。

import sys
from PySide import QtGui, QtCore
class Example(QtGui.QPushButton):
    def __init__(self, parent = None):
        super(Example, self).__init__(parent)
        self.setText('TestMenu')
        self.setToolTip('This is a Test Button')
        menu = QtGui.QMenu(self)
        action_1 = menu.addAction('Action1')
        action_1.setToolTip('This is action 1')
        action_2 = menu.addAction('Action2')
        action_2.setToolTip('This is action 2')
        action_3 = menu.addAction('Action3')
        action_3.setToolTip('This is action 3')
        action_4 = menu.addAction('Action4')
        action_4.setToolTip('This is action 4')
        action_1.hovered.connect(lambda pos = [self], parent = action_1, index = 0: show_toolTip(pos, parent, index))
        action_2.hovered.connect(lambda pos = [self], parent = action_2, index = 1: show_toolTip(pos, parent, index))
        action_3.hovered.connect(lambda pos = [self], parent = action_3, index = 2: show_toolTip(pos, parent, index))
        action_4.hovered.connect(lambda pos = [self], parent = action_4, index = 3: show_toolTip(pos, parent, index))
        self.setMenu(menu)
        self.show()
def show_toolTip(pos, parent, index):
    '''
    **Parameters**
        pos:    list
            list of all parent widget up to the upmost
        parent: PySide.QtGui.QAction
            the parent QAction
        index:  int
            place within the QMenu, beginning with zero
    '''
    position_x = 0
    position_y = 0
    for widget in pos:
        position_x += widget.pos().x()
        position_y += widget.pos().y()
    point = QtCore.QPoint()
    point.setX(position_x)
    point.setY(position_y + index * 22) # set y Position of QToolTip
    QtGui.QToolTip.showText(point, parent.toolTip())
def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    app.exec_()
if __name__ == '__main__':
    main()

不得不说我对此并不完全满意,主要是因为 show_toolTip 函数必须是全局的,因为当我在类中使用它时,lambda 运算符没有识别它(self.show_toolTip )。如果有人有建议,我仍然愿意接受建议。

无需立即显示工具提示,只需在悬停时更新父(菜单)的工具提示,然后等待工具提示显示!因此:

    menu = QtGui.QMenu(self)
    action_1 = menu.addAction('Action1')
    action_1.setToolTip('This is action 1')
    ...
    menu.hovered.connect(self.handleMenuHovered)
def handleMenuHovered(self, action):
    action.parent().setToolTip(action.toolTip())