PyQt:在基类中覆盖“ mousePressEvent”方法时,将“ mousePressEvent”传递给原始小部件

时间:2018-08-23 15:39:57

标签: python pyqt pyqt5

我正在尝试为小部件创建一个全局上下文帮助系统。可以使用ContextHelpBase类扩展所有小部件,并具有将信号发送到Context Help Display小部件所需的所有逻辑。

这个想法是,当用户单击窗口小部件时,它将显示一些上下文帮助。因此,我使mousePressEvent重载以发送信号,但是现在普通按钮和QComboBox行为不起作用,因为我假设自从重写信号以来,我没有在常规事件处理程序上传递信号。 / p>

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

主要问题

如何将鼠标按下事件传递给原始小部件。

其他问题

  1. 使用Python装饰器是否可能
  2. 是否有更好的设计模式更适合这种情况?

1 个答案:

答案 0 :(得分:0)

@eyllanesc关于它的内容看起来像这样:

from PyQt5.QtWidgets import (QApplication, QLabel, QWidget, QPushButton, 
                             QComboBox, QHBoxLayout, QVBoxLayout)
from PyQt5.QtCore    import QObject, pyqtSignal, pyqtSlot,  QEvent, Qt


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 <b>QPushButton</b> Context Help Text"


class ContextHelpComboBox(QComboBox):             # - --> , ContextHelpBaseClass):
    """QPush Button with Context Help"""
    def __init__(self):
        super(ContextHelpComboBox, self).__init__()
        self.helpText = "This is <b>QComboBox</b> 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")

        self.comboBox = ContextHelpComboBox()     # + self.
        self.comboBox.addItem("Test Item 1")
        self.comboBox.addItem("Test Item 2")
        self.comboBox.addItem("Test Item 3")

        self.comboBox.installEventFilter(self)    # <- Installs an event filter filterObj on this object. 

        self.helpTextDisplay = ContexHelpDisplay("Context Help")

        vBox = QVBoxLayout()
        vBox.addWidget(button)
        vBox.addWidget(self.comboBox)

        hBox = QHBoxLayout()
        hBox.addLayout(vBox)
        hBox.addWidget(self.helpTextDisplay)
        self.setLayout(hBox)

    # Filters events if this object has been installed as an event filter for the watched object.
    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseButtonPress and obj is self.comboBox:
            self.helpTextDisplay.setText(self.comboBox.helpText)
        return super(MainWindow, self).eventFilter(obj, event)


if __name__ == "__main__":
    app = QApplication([])
    ex  = MainWindow()
    exit(app.exec_())

enter image description here