【问题标题】:PyQt5 log a signalPyQt5 记录一个信号
【发布时间】:2016-07-28 13:52:48
【问题描述】:

我正在尝试在信号和插槽之间创建一个简单的连接,但发现自己在尝试调用额外函数时遇到了困难。我有两个选择。这是调用我的课程的代码。

(选项 1)

self.flip = MyClass("Flip Image")
self.flip.clicked.connect(self.do_flip)

QWidget 然后由我的类实例化,其主要目的是记录发出的信号。这就是我认为应该实现我的课程的方式:

class MyClass(QPushButton):

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    def mousePressEvent(self, *args, **kwargs):
        self.log_info()

    def log_info(self):
        log(self._name)

我不明白为什么永远不会调用 do_flip 插槽?这对我来说毫无意义,所以我尝试通过

覆盖点击的信号

(选项 2)

class MyClass(QPushButton):

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    def clicked(self, *args, **kwargs):
        self.log_info()
        #add connect() here?

    def log_info(self):
        log(self._name)

但是有了这段代码,我得到了一个友好的AttributeError: 'function' object has no attribute 'connect'。我找不到关于 clicked 方法以及它如何调用连接的任何文档。有没有办法让我建立点击插槽的连接,还是我必须创建自己的信号?我发现这在尝试覆盖其他发出特定值的信号时会变得非常有用。

如果是这样,这会导致我:

最后的手段 - 我自己的信号

类会这样调用:

self.flip = MyClass("Flip Image")
self.flip.mysig.connect(self.do_flip)

并像这样实现:

class MyClass(QPushButton):

    mysig = pyqtSignal()

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    def mousePressEvent(self, *args, **kwargs):
        self.mysig.emit()
        self.log_info()

    def log_info(self):
        log(self._name)

这很有效。但我不确定我的实现是否有意义。感觉有点hacky。我不想使用这个最后的选项,我希望有一个更清洁的选项。

【问题讨论】:

    标签: python qt pyqt signals-slots


    【解决方案1】:

    选项 1 中,您将覆盖 QPushButtonmousePressEvent 方法,而不使用 super 调用默认实现,我相信这就是为什么 clicked 信号永远不会出现的原因发出。例如:

    class MyClass(QPushButton):
    
    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name
    
    def mousePressEvent(self, event):
        self.log_info()
        super().mousePressEvent(event)
    
    def log_info(self):
        log(self._name)
    

    选项2中,您将clicked 声明为普通的python 可调用对象,而它应该是pyqtSignal()。而且这绝对不是要走的路。

    实现所需的正确方法是对同一信号使用多个插槽,即:

    class MyClass(QPushButton):
    
        def __init__(self, name: str) -> None:
            super().__init__(name)
            self._name = name
    
        @pyqtSlot()
        def log_info(self):
            log(self._name)
    
    self.flip = MyClass("Flip Image")
    self.flip.clicked.connect(self.do_flip)
    self.flip.clicked.connect(self.flip.log_info)
    

    【讨论】:

    • 在选项2中,有没有办法覆盖clicked pyqtSignal 给出的QAbstractButton 以添加对日志的调用?
    • clicked 不是函数,而是 pyqtSignal。正如我在帖子中解释的那样,这绝对不是要走的路。
    • 假设我简化了一点,我不希望按照您向我展示的方式从一个信号连接多个插槽。
    • 那么我会选择选项 1,即使我提出的解决方案更清洁。
    • 可以像mousePressEvent() 调用其超类一样覆盖信号吗?
    猜你喜欢
    • 2016-07-17
    • 2019-07-31
    • 1970-01-01
    • 2015-05-07
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2019-04-15
    相关资源
    最近更新 更多