问题
I'm doing an app with in GUI written with PySide
. I set a QMenu
on a QPushButton
, added several QActions
via QMenu.addAction
. To further explain these actions to the user I added QToolTip
's to these with QAction.setToolTip
.
When I run the GUI now my QToolTip
won't show. The example posted below reproduces the same issue, any ideas?
Thanks in advance
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()
回答1:
In Qt-5.1 or later, you can simply use QMenu.setToolTipsVisible, and the menu items will show their tooltips as expected (see QTBUG-13663):
menu.setToolTipsVisible(True)
However, for Qt-4.* and Qt-5.0, the situation is different. If an action is added to a toolbar, its tooltip will be shown; but if the same action is added to a QMenu
, it won't be, and there is no built-in API to change that. There are a couple of ways to work around this. One is to use status tips instead, which will show the menu-item information in the status-bar. The other is to implement the menu-item tooltip functionality yourself using the QMenu.hovered signal and 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))
回答2:
Actually you don't have to do any workaround to display your tooltip, since Qt 5.1, you can use QMenu's property toolTipsVisible, which is by default set to false
.
See the related Qt suggestion.
回答3:
With ekhumoro helping me on the way got to this solution. It's probably not the most beautiful thing, and the code below positions the menu and the tool tips somewhat arkward, but in my actual programm it looks quite neat.
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()
I have to say I'm not perfectly happy with this, mainly because the show_toolTip
function has to be global, for the lambda operator didn't recognize it when I had it in the class (self.show_toolTip
). I'm still open for suggesetions if someone has a suggestion.
回答4:
Instead of showing tooltip immediately one can just update the tooltip of the parent (menu) when hovering and wait for the tooltip to be shown! Therefore:
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())
来源:https://stackoverflow.com/questions/21725119/why-wont-qtooltips-appear-on-qactions-within-a-qmenu