【发布时间】:2019-01-30 01:16:15
【问题描述】:
我正在尝试为小部件创建一个全局上下文帮助系统。所有小部件都可以使用 ContextHelpBase 类进行扩展,并具有向上下文帮助显示小部件发送信号所需的所有逻辑。
这个想法是当用户点击一个小部件时,它会显示一些上下文帮助。所以我重载了mousePressEvent 以发送信号,但现在正常的按钮和 QComboBox 行为不起作用,因为我假设我没有在正常事件处理程序上传递信号,因为我正在覆盖它。
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QPushButton, QComboBox, QHBoxLayout, QVBoxLayout
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
class ContextHelpSignals(QObject):
""" Used to send signals globally through the application
Eventually will be a Global Singelton
"""
textHelp = pyqtSignal(str)
def __init__(self):
super(ContextHelpSignals, self).__init__()
#Eventually will be a Global Singleton
_contextHelp = ContextHelpSignals()
class ContextHelpBaseClass(QObject):
"""All Widget that have context help inherits this class"""
def __init__(self, **kw):
super(ContextHelpBaseClass, self).__init__()
self.helpText = None
def mousePressEvent(self, event):
""" THIS DISABLE WIDGETS NORMAL CLICK BEHAVIOR """
_contextHelp.textHelp.emit(self.helpText)
# How can emit a signal and then pass this event to the normal widget
print(type(super()))
def SetHelpText(self, helpText):
self.helpText = helpText
class ContexHelpDisplay(QLabel):
"""Dislpay Context Help frow widgets that have Context Help"""
def __init__(self, text):
super(ContexHelpDisplay, self).__init__()
self.setText(text)
_contextHelp.textHelp.connect(self.__displayHelp)
# Need to pass event to original widget
# type.mousePresseEvent() - How do I get type?
@pyqtSlot(str)
def __displayHelp(self, contextHelpText):
self.setText(contextHelpText)
class ContextHelpButton(QPushButton, ContextHelpBaseClass):
"""QPush Button with Context Help"""
def __init__(self, text):
super(ContextHelpButton, self).__init__()
self.setText(text)
self.helpText = "This is QPushButton Context Help Text"
## It would be nice if I could use a Python Decorator, but
## don't know how yet.
## @ContextHelp
class ContextHelpComboBox(QComboBox, ContextHelpBaseClass):
"""QPush Button with Context Help"""
def __init__(self):
super(ContextHelpComboBox, self).__init__()
self.helpText = "This is QComboBox Context Help Text"
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent=parent)
self.setupUI()
def setupUI(self):
self.resize(250, 150)
self.setWindowTitle('Context Help Example')
self.show()
button = ContextHelpButton("Test Button")
comboBox = ContextHelpComboBox()
comboBox.addItem("Test Item 1")
comboBox.addItem("Test Item 2")
comboBox.addItem("Test Item 3")
helpTextDisplay = ContexHelpDisplay("Context Help")
vBox = QVBoxLayout()
vBox.addWidget(button)
vBox.addWidget(comboBox)
hBox = QHBoxLayout()
hBox.addLayout(vBox)
hBox.addWidget(helpTextDisplay)
self.setLayout(hBox)
if __name__ == "__main__":
app = QApplication([])
ex = MainWindow()
exit(app.exec_())
主要问题:
如何将鼠标按下事件传递给原始小部件。
其他问题:
- 这可以通过 Python 装饰器实现吗
- 是否有更好的设计模式更适合这种情况?
【问题讨论】:
-
你想听到其他小部件的点击事件吗?为什么不使用 eventFilter?
-
我正在尝试扩展任何小部件的 mousePressEvent 以在执行原始小部件 mousePressEvent 之外发出信号。
-
这种设计不是 Qt 推荐的,如果你的任务是在你按下任何小部件时发出信号,你应该使用事件过滤器。