PYQT QTimer 没有启动
PYQT QTimer does not start
我正在将 PyQt 5 用于 GUI 应用程序,但我遇到了线程问题。
有一个关闭按钮,一旦点击它,QTimer 就会启动,然后它会在一个 while 循环中等待,该循环以 QTimer 处理程序中正在递增的变量值为条件。
问题是定时器没有启动。有趣的是,如果我评论 while 循环,计时器会正常工作。
代码如下:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QHBoxLayout
import sys
import time
class MyClass(QMainWindow):
myTimer = None
myCounter = 0
def __init__(self):
QMainWindow.__init__(self)
myButton = QPushButton(text='Close')
myButton.clicked.connect(self.myButtonClicked)
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
ly = QHBoxLayout()
ly.addWidget(myButton)
centralWidget.setLayout(ly)
self.myTimer = QTimer()
self.myTimer .timeout.connect(self.__myTimerHandler)
def myButtonClicked(self):
self.myCounter= 0
self.myTimer.start(1000)
print('Loop Start')
while self.myCounter < 10:
self.__DoNothing()
print('Loop END')
def __DoNothing(self):
print('Nothing')
#time.sleep(2)
def __myTimerHandler(self):
self.myCounter = self.myCounter + 1
print('Counter:' + str(self.myCounter))
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MyClass()
mainWin.show()
sys.exit( app.exec_() )
输出:
Loop Start
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
正如我所解释的,使用此代码 QTImer(我的计时器)不会启动。但是如果我评论 while 循环,QTimer 会正确启动并且每秒调用一次处理程序。
注释掉 DoNothing 函数中的 time.sleep 行没有帮助。
我可以想象这是关于多线程和访问同一个变量的问题,但我不知道如何解决它。
正如@musicamante 在评论中提到的“在主 Qt 线程中不应发生任何阻塞函数或循环”。在问题提供的代码中,线程实际上正在启动,但由于阻塞循环,处理程序没有机会被调用。
正如@ekhumoro 在评论中提到的,解决方案是使用“QApplication.processEvents()”在等待循环中处理事件。并在“__DoNothing”函数中添加睡眠函数。
所以最终的解决方案如下:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QHBoxLayout
import sys
import time
class MyClass(QMainWindow):
myTimer = None
myCounter = 0
def __init__(self):
QMainWindow.__init__(self)
myButton = QPushButton(text='Close')
myButton.clicked.connect(self.myButtonClicked)
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
ly = QHBoxLayout()
ly.addWidget(myButton)
centralWidget.setLayout(ly)
self.myTimer = QTimer()
self.myTimer .timeout.connect(self.__myTimerHandler)
def myButtonClicked(self):
self.myCounter= 0
self.myTimer.start(1000)
print('Loop Start')
while self.myCounter < 10:
self.__DoNothing()
QApplication.processEvents()
print('Loop END')
def __DoNothing(self):
print('Nothing')
time.sleep(0.250)
def __myTimerHandler(self):
self.myCounter = self.myCounter + 1
print('Counter:' + str(self.myCounter))
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MyClass()
mainWin.show()
sys.exit( app.exec_() )
并且输出将完全符合预期,如下所示:
Loop Start
Nothing
Nothing
Nothing
Nothing
Counter:1
Nothing
Nothing
Nothing
Nothing
Counter:2
Nothing
Nothing
Nothing
Nothing
Counter:3
Nothing
Nothing
Nothing
Loop Start
Nothing
Nothing
Nothing
Nothing
Counter:1
Nothing
Nothing
Nothing
Nothing
Counter:2
Nothing
Nothing
Nothing
Nothing
Nothing
Counter:3
Nothing
Nothing
Nothing
Counter:4
Nothing
Nothing
Nothing
Nothing
Counter:5
Nothing
Nothing
Nothing
Nothing
Counter:6
Nothing
Nothing
Nothing
Nothing
Counter:7
Nothing
Nothing
Nothing
Nothing
Counter:8
Nothing
Nothing
Nothing
Nothing
Counter:9
Nothing
Nothing
Nothing
Nothing
Counter:10
Loop END
Loop END
显然两个计数器回调的时间差不一定相同
我正在将 PyQt 5 用于 GUI 应用程序,但我遇到了线程问题。
有一个关闭按钮,一旦点击它,QTimer 就会启动,然后它会在一个 while 循环中等待,该循环以 QTimer 处理程序中正在递增的变量值为条件。
问题是定时器没有启动。有趣的是,如果我评论 while 循环,计时器会正常工作。
代码如下:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QHBoxLayout
import sys
import time
class MyClass(QMainWindow):
myTimer = None
myCounter = 0
def __init__(self):
QMainWindow.__init__(self)
myButton = QPushButton(text='Close')
myButton.clicked.connect(self.myButtonClicked)
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
ly = QHBoxLayout()
ly.addWidget(myButton)
centralWidget.setLayout(ly)
self.myTimer = QTimer()
self.myTimer .timeout.connect(self.__myTimerHandler)
def myButtonClicked(self):
self.myCounter= 0
self.myTimer.start(1000)
print('Loop Start')
while self.myCounter < 10:
self.__DoNothing()
print('Loop END')
def __DoNothing(self):
print('Nothing')
#time.sleep(2)
def __myTimerHandler(self):
self.myCounter = self.myCounter + 1
print('Counter:' + str(self.myCounter))
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MyClass()
mainWin.show()
sys.exit( app.exec_() )
输出:
Loop Start
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
正如我所解释的,使用此代码 QTImer(我的计时器)不会启动。但是如果我评论 while 循环,QTimer 会正确启动并且每秒调用一次处理程序。
注释掉 DoNothing 函数中的 time.sleep 行没有帮助。
我可以想象这是关于多线程和访问同一个变量的问题,但我不知道如何解决它。
正如@musicamante 在评论中提到的“在主 Qt 线程中不应发生任何阻塞函数或循环”。在问题提供的代码中,线程实际上正在启动,但由于阻塞循环,处理程序没有机会被调用。
正如@ekhumoro 在评论中提到的,解决方案是使用“QApplication.processEvents()”在等待循环中处理事件。并在“__DoNothing”函数中添加睡眠函数。
所以最终的解决方案如下:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QHBoxLayout
import sys
import time
class MyClass(QMainWindow):
myTimer = None
myCounter = 0
def __init__(self):
QMainWindow.__init__(self)
myButton = QPushButton(text='Close')
myButton.clicked.connect(self.myButtonClicked)
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
ly = QHBoxLayout()
ly.addWidget(myButton)
centralWidget.setLayout(ly)
self.myTimer = QTimer()
self.myTimer .timeout.connect(self.__myTimerHandler)
def myButtonClicked(self):
self.myCounter= 0
self.myTimer.start(1000)
print('Loop Start')
while self.myCounter < 10:
self.__DoNothing()
QApplication.processEvents()
print('Loop END')
def __DoNothing(self):
print('Nothing')
time.sleep(0.250)
def __myTimerHandler(self):
self.myCounter = self.myCounter + 1
print('Counter:' + str(self.myCounter))
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MyClass()
mainWin.show()
sys.exit( app.exec_() )
并且输出将完全符合预期,如下所示:
Loop Start
Nothing
Nothing
Nothing
Nothing
Counter:1
Nothing
Nothing
Nothing
Nothing
Counter:2
Nothing
Nothing
Nothing
Nothing
Counter:3
Nothing
Nothing
Nothing
Loop Start
Nothing
Nothing
Nothing
Nothing
Counter:1
Nothing
Nothing
Nothing
Nothing
Counter:2
Nothing
Nothing
Nothing
Nothing
Nothing
Counter:3
Nothing
Nothing
Nothing
Counter:4
Nothing
Nothing
Nothing
Nothing
Counter:5
Nothing
Nothing
Nothing
Nothing
Counter:6
Nothing
Nothing
Nothing
Nothing
Counter:7
Nothing
Nothing
Nothing
Nothing
Counter:8
Nothing
Nothing
Nothing
Nothing
Counter:9
Nothing
Nothing
Nothing
Nothing
Counter:10
Loop END
Loop END
显然两个计数器回调的时间差不一定相同