【问题标题】:Signal in PySide not emitted when called by a timerPySide 中的信号在被计时器调用时未发出
【发布时间】:2015-05-18 15:50:43
【问题描述】:

我需要定期发出信号。计时器执行某些功能,该功能会发出我想要的信号。由于某种原因,这个函数没有被发出。我能够在最少的代码上重现错误(见下文)。如果我在没有计时器的情况下做同样的事情,一切正常:

from threading import Timer
import time
from PySide import QtCore

class testSignals(QtCore.QObject):
    signal = QtCore.Signal();
    def __init__(self):
        QtCore.QObject.__init__(self)

    def run(self):
        self.signal.emit()

class testConnection():
    @QtCore.Slot()
    def receiveMe(self):
        print('Signal received')

    # signal is emmited when data is changed
    def __init__(self):
        test = testSignals()
        test.signal.connect(self.receiveMe)
        test.run();

test = testConnection()

我能够在以下代码中重现我的问题:

from threading import Timer
import time
from PySide import QtCore

class testSignals(QtCore.QObject):

    signal = QtCore.Signal();

    def __init__(self):
        self.is_running = False
        QtCore.QObject.__init__(self)
        self.start()

    def emitMe(self):
        self.is_running = False
        self.start()
        # print("emitMe")
        self.signal.emit()

    def start(self):
        if not self.is_running:
            self._timer = Timer(0.2, self.emitMe)
            self._timer.start()
            self.is_running = True

    def stop(self):
        self._timer.cancel()
        self.is_running = False

class testConnection():
    @QtCore.Slot()
    def receiveMe(self):
        print('Signal received')

    # signal is emmited when data is changed
    def __init__(self):
        test = testSignals()
        test.signal.connect(self.receiveMe)
        test.start();
        time.sleep(2.0)
        test.stop();

test = testConnection()

“收到的信号”短语没有打印在屏幕上。

【问题讨论】:

  • 如果没有事件循环,信号将无法工作。
  • 您能详细说明一下吗?我认为这是因为线程超出了 Qt 的控制,但我还没有找到解决它的方法。我正在讨论这个:stackoverflow.com/questions/9712461/…
  • 对于直接信号/插槽连接,不需要事件循环(甚至不需要应用程序对象)。但是对于跨线程连接,信号被发布到事件队列并异步处理。当然,您可能需要为此使用QThread - 尽管我认为可能可以将某种解决方法组合在一起(不要问我如何)。但无论如何:你为什么不使用QTimer?

标签: python qt pyside


【解决方案1】:

正如@ekhumoro 在 cmets 中所说,QTimer 帮助很大。我需要一个事件循环。我正在发布代码以使答案有效。我使用 QTimer 重写了它,这让一切变得更加简单。请注意,我需要调用 QCoreApplication 来运行线程。同样,这只是重现我需要做的最少的代码。

import time
from PySide import QtCore
from probeConnection import ProbeConnection 

class testSignals(QtCore.QObject):

    def __init__(self):
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.tick)
        self.start()

    def tick(self):
        print("tick")

    def getData(self):
        return time.strftime('%H:%M:%S')

    def start(self):
        self.timer.start(1000)

    def stop(self):
        self.timer.stop()

class testConnection():
    def receiveMe(self):
        print('time: ' + self.test.getData())

    def __init__(self):
        self.test = testSignals()
        self.test.timer.timeout.connect(self.receiveMe)


app = QtCore.QCoreApplication([])
test = testConnection()
timer = QtCore.QTimer()
timer.singleShot(4000,app.exit)
app.exec_()

它产生:

tick
time: 13:23:37
tick
time: 13:23:38
tick
time: 13:23:39
tick
time: 13:23:40

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2015-11-05
    • 2018-04-15
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    相关资源
    最近更新 更多