首页 > 解决方案 > 如果在连接信号之前调用 Slot,则无法连接到 QTimer Slot 中发送的信号

问题描述

Windows 上的 Py3 / PySide2 5.13.2

我有两个课程:一个时钟发出带有计时器的信号/一个显示打印时间

import PySide2
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtCore import Signal, Slot 

import time
import sys

class MyClock(QtCore.QObject):
    """
    Must inherited QObject to emit a Signal
    """
    def __init__(self):
        super().__init__()
        
        self.timer = QtCore.QTimer()
        self.timer.start(1000.)
    
    def Start(self):
        self.timer.timeout.connect(self.Tick)
                
    def Tick(self):
        t = time.time()
        print ("Emit: ",t)
        self.emit(QtCore.SIGNAL("SEND(float)"),t)  
        
class ClockDisplay():
    def __init__(self):
        super(ClockDisplay,self).__init__()

    def Display(self,t):
        print ("Received: ", t)

BUG:在将信号连接到显示器之前,调用 QTimer 插槽 (Tick) (clock.Start):

if __name__ == "__main__":
    
    app = QApplication(sys.argv)
    
    clock = MyClock()
    clock.Start()

    display = ClockDisplay()

    clock.connect(QtCore.SIGNAL("SEND(float)"),display.Display)

警告消息 *** 排序警告 *** QMetaObject 'MyClock' 中的信号和插槽未正确排序,这可能会导致问题。1 槽滴答() 2!信号 SEND(float) clock.connect(QtCore.SIGNAL("SEND(float)"),display.Display)

显示器不接收 SEND。

WORKS:将信号连接到显示器后,调用 QTimer 插槽 (Tick) (clock.Start)。

if __name__ == "__main__":
    
    app = QApplication(sys.argv)
    
    clock = MyClock()

    display = ClockDisplay()

    clock.connect(QtCore.SIGNAL("SEND(float)"),display.Display)
    clock.Start()

标签: pythonpython-3.xpyside2

解决方案


对我来说,在这两种情况下,它们仅在我在第一种情况下收到警告时才起作用。此警告仅表明信号和槽应该在 QMetaObject 中排序,但在这种情况下它们不是因为首先添加了“Tick”槽,然后添加了“SEND”信号。可能 Qt 或 shiboken 以某种需要排序的方式使用信号和插槽,因此它会引发该警告。

我的建议是不要使用创建信号和槽的旧语法,而是使用“信号”和“槽”:

from PySide2 import QtCore

import time
import sys


class MyClock(QtCore.QObject):
    SEND = QtCore.Signal(float)

    def __init__(self):
        super().__init__()

        self.timer = QtCore.QTimer()
        self.timer.start(1000.0)

    def Start(self):
        self.timer.timeout.connect(self.Tick)

    def Tick(self):
        t = time.time()
        print("Emit: ", t)
        self.SEND.emit(t)


class ClockDisplay:
    def Display(self, t):
        print("Received: ", t)


if __name__ == "__main__":

    app = QtCore.QCoreApplication(sys.argv)

    clock = MyClock()
    clock.Start()

    display = ClockDisplay()

    clock.SEND.connect(display.Display)

    sys.exit(app.exec_())

推荐阅读