我正在使用 PyQT5 制作一个轻量级 GUI 程序。
但现在我面临一些有关线程的问题。
我只是做了简单的测试程序,如底部:
程序只是尝试将数字附加到文本框,但它崩溃了。
我不知道为什么,但我可以通过删除评论(time.sleep)来阻止它
import sys
import threading
import time
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class Some(QWidget):
e = threading.Event()
def btnfunc(self):
self.e.set()
def __init__(self):
super().__init__()
self.myButton = QPushButton('do next')
self.logs = QTextEdit()
self.mylay = QVBoxLayout()
self.mylay.addWidget(self.myButton)
self.mylay.addWidget(self.logs)
self.setLayout(self.mylay)
self.setGeometry(300, 300, 300, 550)
self.setWindowTitle('mytest')
self.show()
t = threading.Thread(target=self.myfunc, args=( ))
t.start()
self.myButton.clicked.connect(self.btnfunc)
def myfunc(self):
for i in range(300):
# time.sleep(0.4)
self.logs.append(str(i))
if i == 20:
self.e.wait()
app = QApplication(sys.argv)
ex = Some()
sys.exit(app.exec_())
如果把时间设置得高一些就更好了。
我认为这是因为资源访问,因为它是pyQT5 GUI。
所以我找到了 QThread。我尝试像底部一样,
import sys
import time
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class Some(QWidget):
qw = QWaitCondition()
qm = QMutex()
def btnfunc(self):
self.qw.wakeAll()
def __init__(self):
super().__init__()
self.myButton = QPushButton('do next')
self.logs = QTextEdit()
self.mylay = QVBoxLayout()
self.mylay.addWidget(self.myButton)
self.mylay.addWidget(self.logs)
self.setLayout(self.mylay)
self.setGeometry(300, 300, 300, 550)
self.setWindowTitle('mytest')
self.show()
self.myButton.clicked.connect(self.btnfunc)
self.thread = QThread()
self.thread.started.connect(self.myfunc)
self.thread.start()
def myfunc(self):
for i in range(300):
self.logs.append(str(i))
if i == 20:
self.qw.wait(self.qm)
app = QApplication(sys.argv)
ex = Some()
sys.exit(app.exec_())
但是崩溃了,不起作用。并尝试了 QThread+threading.Event()。它卡住了 GUI。
现在我不知道如何继续......
编辑: 我刚刚意识到线程。不应从除 QThread 之外的其他线程访问。 然后我会继续查找QWaitCondition
最佳答案
您不应该通过多线程直接控制 GUI。由于两个不同的线程试图控制 GUI,这会导致卡住或崩溃。 我从这里了解了这个概念http://www.xyzlang.com/python/PyQT5/pyqt_multithreading.html
这是您可以完美运行的代码。
import sys
import threading
import time
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
# Added new
class Communicate(QObject):
signal = pyqtSignal(str)
class Some(QWidget):
e = threading.Event()
def btnfunc(self):
self.e.set()
def __init__(self):
super().__init__()
#communicate object
self.comm = Communicate()
self.comm.signal.connect(self.append_data)
self.myButton = QPushButton('do next')
self.logs = QTextEdit()
self.mylay = QVBoxLayout()
self.mylay.addWidget(self.myButton)
self.mylay.addWidget(self.logs)
self.setLayout(self.mylay)
self.setGeometry(300, 300, 300, 550)
self.setWindowTitle('mytest')
self.show()
t = threading.Thread(target=self.myfunc, args=( ))
t.start()
self.myButton.clicked.connect(self.btnfunc)
def myfunc(self):
for i in range(300):
# time.sleep(0.4)
#self.logs.append(str(i))
self.comm.signal.emit(str(i))
if i == 20:
self.e.wait()
def append_data(self, data):
self.logs.append(data)
app = QApplication(sys.argv)
ex = Some()
sys.exit(app.exec_())
关于python - 如何在 PyQT5 中暂停/播放线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33969053/