Почему QToolTips не появляется на QActions в QMenu

Я делаю приложение с помощью GUI, написанного с PySide. Я установил QMenu на QPushButton, несколько QActions via QMenu.addAction. Для дальнейшего объяснения этих действий пользователю я добавил QToolTipС этим с QAction.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()

4 ответов


в Qt-5.1 или более поздней версии, вы можете просто использовать QMenu.setToolTipsVisible, и пункты меню будут показывать свои подсказки, как ожидалось (см. QTBUG-13663):

    menu.setToolTipsVisible(True)

однако, для Qt-4.* и Qt-5.0, ситуация другая. Если действие добавляется на панель инструментов, его всплывающая подсказка будет будет показано; но если то же самое действие добавляется к QMenu, этого не будет, и нет встроенного API для изменения этого. Есть несколько способов обойти этот. Один из них-использовать советы по статусу вместо этого, который покажет информацию о пункте меню в строке состояния. Другой - реализовать функцию всплывающей подсказки меню самостоятельно с помощью QMenu.завис сигнал и QToolTip.этой акции:

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

На самом деле вам не нужно делать никаких обходных путей для отображения всплывающей подсказки, так как Qt 5.1, вы можете использовать свойство QMenu toolTipsVisible, который по умолчанию установлен в false.

посмотреть связанное предложение Qt.


С помощью ekhumoro, помогая мне на пути к этому решению. Это, вероятно, не самая красивая вещь, и код ниже позиционирует меню и подсказки инструментов несколько arkward, но в моей реальной программе это выглядит довольно аккуратно.

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 функция должна быть глобальной, поскольку лямбда-оператор не распознал ее, когда она была у меня в классе (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())