在 PyQt QDialog 的标题栏右侧(见下文,“x”旁边)有一个“?”这应该帮助用户查询对话框窗口上任何其他小部件的帮助。
我应该做什么(以编程方式)才能让它工作。一旦 ”?” isClicked,应该能够捕获下一个单击的小部件并提供工具提示或类似的东西。在PyQt中,我不知道如何捕获“?”上的isClicked事件。
我看过一些帖子,其中的问题是如何制作“?”消失了,但是那里的讨论使用Qt,而不是PyQt,所以我不明白它,而且他们没有谈论我需要的东西。我需要让它按预期工作。请参阅How can I hide/delete the "?" help button on the "title bar" of a Qt Dialog?和 PyQt4 QInputDialog and QMessageBox window flags
最佳答案
您可以设置 whatsThis
属性到您想要的任何小部件:
self.someWidget.setWhatsThis('hello!')
从那时起,每当您单击“?”时按钮,然后单击该小部件,将显示带有该文本的工具提示。
由于“这是什么”模式是单独设置给小部件的,因此没有简单的方法可以全局捕获它(据我所知),因为如果小部件没有设置“whatsthis”属性,则该功能将无法使用.
另外,每当您进入“这是什么”模式时,光标可能会根据“whatsthis”属性的内容而变化:如果未设置,光标可能会显示“已禁用”图标。
我已经为这个问题创建了一个基本的解决方法,只要模式被激活,它就会自动启用任何子窗口小部件的whatsthis(如果尚未设置):只要EnterWhatsThisMode
被触发,它就会自动安装一个充当事件过滤器的自定义对象,并在调用 Whatsthis 事件时发出信号;一旦模式退出,过滤器就会被删除。
我为事件过滤器使用了一个单独的对象,因为无法知道小部件中已经安装了哪些事件过滤器,并且如果您已经安装了父级的事件过滤器,那么自动删除它将会是一个问题。
class WhatsThisWatcher(QtCore.QObject):
whatsThisRequest = QtCore.pyqtSignal(QtWidgets.QWidget)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.WhatsThis:
self.whatsThisRequest.emit(source)
return super(WhatsThisWatcher, self).eventFilter(source, event)
class W(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
layout = QtWidgets.QVBoxLayout(self)
hasWhatsThisButton = QtWidgets.QPushButton('Has whatsThis')
layout.addWidget(hasWhatsThisButton)
hasWhatsThisButton.setWhatsThis('I am a button!')
noWhatsThisButton = QtWidgets.QPushButton('No whatsThis')
layout.addWidget(noWhatsThisButton)
self.whatsThisWatchedWidgets = []
self.whatsThisWatcher = WhatsThisWatcher()
self.whatsThisWatcher.whatsThisRequest.connect(self.showCustomWhatsThis)
whatsThisButton = QtWidgets.QPushButton('Set "What\'s this" mode')
layout.addWidget(whatsThisButton)
whatsThisButton.clicked.connect(QtWidgets.QWhatsThis.enterWhatsThisMode)
def event(self, event):
if event.type() == QtCore.QEvent.EnterWhatsThisMode:
for widget in self.findChildren(QtWidgets.QWidget):
if not widget.whatsThis():
# install the custom filter
widget.installEventFilter(self.whatsThisWatcher)
# set an arbitrary string to ensure that the "whatsThis" is
# enabled and the cursor is correctly set
widget.setWhatsThis('whatever')
self.whatsThisWatchedWidgets.append(widget)
elif event.type() == QtCore.QEvent.LeaveWhatsThisMode:
while self.whatsThisWatchedWidgets:
widget = self.whatsThisWatchedWidgets.pop()
# reset the whatsThis string to none and uninstall the filter
widget.setWhatsThis('')
widget.removeEventFilter(self.whatsThisWatcher)
return super(W, self).event(event)
def showCustomWhatsThis(self, widget):
widgetPos = widget.mapTo(self, QtCore.QPoint())
QtWidgets.QWhatsThis.showText(
QtGui.QCursor.pos(),
'There is no "what\'s this" for {} widget at coords {}, {}'.format(
widget.__class__.__name__, widgetPos.x(), widgetPos.y()),
widget)
关于此的一些注释:
- 我使用了一个按钮来激活 Whatsthis 模式,因为在 Linux 上的窗口管理器上没有相应的窗口标题按钮;
- 某些小部件可能包含子小部件,您将获得这些子小部件而不是“主”小部件(最常见的情况是 QAbstractScrollArea 后代,例如 QTextEdit 或 QGraphicsView,它们可能返回视口(viewport)、内部“小部件”或滚动条);
关于python - 如何使用 PyQT 对话框标题栏上的 "?"(这个小部件是什么),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59078185/