我正在开发一个应用程序,它使用多个线程从各种网络设备收集数据。我使用PyQT在GUI上显示收集的数据。我在我的应用程序(而不是QThread)中使用常规python线程(从线程,线程)。为了更新不同线程上的GUI,我使用了一个锁(thread.allocate_lock())。因此,无论何时GUI更新都会发生,我都会调用锁,更新GUI。对此有何担忧?PyQT和线程
Q
PyQT和线程
1
A
回答
3
我敢肯定,从不同线程更新GUI在Qt中是危险的,即使你试图在你自己的代码中锁定东西。首先,Qt可能会在主线程上执行自己的事件处理,并且它不会获取您的锁以保护它可能会修改的对象。 On this page在Qt文档中,QWidget
不可重入或线程安全的事实明确提及。
我建议您将收集的数据或其处理版本发布回主线程。使用排队信号/插槽连接或自定义QEvent
和QApplication::postEvent
来执行此操作。在jkerian提到的前一个问题中,它表示如果您希望事件发布能够正常工作,则必须使用QThread
而不是python的线程。
0
我使用pyqtSignal和Python的线程。您可以创建线程,并在线程完成时发送信号来更新GUI。
3
这是一个很晚的回复,但我想分享我发现的内容。这是WickedDevice博客的代码,我发现有助于了解线程和PyQt的:
#authors: Dirk Swart, Doudewijn Rempt, Jacob Hallen
import sys, time, threading, random, Queue
from PyQt4 import QtGui, QtCore as qt
import serial
SERIALPORT = 'COM6'
class GuiPart(QtGui.QMainWindow):
def __init__(self, queue, endcommand, *args):
QtGui.QMainWindow.__init__(self, *args)
self.setWindowTitle('Arduino Serial Demo')
self.queue = queue
# We show the result of the thread in the gui, instead of the console
self.editor = QtGui.QTextEdit(self)
self.setCentralWidget(self.editor)
self.endcommand = endcommand
def closeEvent(self, ev):
self.endcommand()
def processIncoming(self):
"""
Handle all the messages currently in the queue (if any).
"""
while self.queue.qsize():
try:
msg = self.queue.get(0)
# Check contents of message and do what it says
# As a test, we simply print it
self.editor.insertPlainText(str(msg))
except Queue.Empty:
pass
class ThreadedClient:
"""
Launch the main part of the GUI and the worker thread. periodicCall and
endApplication could reside in the GUI part, but putting them here
means that you have all the thread controls in a single place.
"""
def __init__(self):
# Create the queue
self.queue = Queue.Queue()
# Set up the GUI part
self.gui=GuiPart(self.queue, self.endApplication)
self.gui.show()
# A timer to periodically call periodicCall :-)
self.timer = qt.QTimer()
qt.QObject.connect(self.timer,
qt.SIGNAL("timeout()"),
self.periodicCall)
# Start the timer -- this replaces the initial call to periodicCall
self.timer.start(100)
# Set up the thread to do asynchronous I/O
# More can be made if necessary
self.running = 1
self.thread1 = threading.Thread(target=self.workerThread1)
self.thread1.start()
def periodicCall(self):
"""
Check every 100 ms if there is something new in the queue.
"""
self.gui.processIncoming()
if not self.running:
root.quit()
def endApplication(self):
self.running = 0
def workerThread1(self):
"""
This is where we handle the asynchronous I/O.
Put your stuff here.
"""
while self.running:
#This is where we poll the Serial port.
#time.sleep(rand.random() * 0.3)
#msg = rand.random()
#self.queue.put(msg)
ser = serial.Serial(SERIALPORT, 115200)
msg = ser.readline();
if (msg):
self.queue.put(msg)
else: pass
ser.close()
if __name__ == "__main__":
#rand = random.Random()
root = QtGui.QApplication(sys.argv)
client = ThreadedClient()
sys.exit(app.exec_())
相关问题
- 1. PyQt和Maya,线程= False?
- 2. PyQt的线程从线程
- 3. pyQt和线程应用程序崩溃
- 4. PyQT类e线程
- 5. PyQt中的线程和信号问题
- 6. PyQt的多线程例子
- 7. PyQt线程属性错误
- 8. PyQt信号跨线程
- 9. 终端线程使用PyQt
- 10. PyQt中的线程化
- 11. 线程化函数-PyQt GUI
- 12. Python - 使用PyQt进行线程编程
- 13. 应用程序线程和Qt线程之间的清晰分离(Python-PyQt)
- 14. PyQt - 从另一个线程修改GUI
- 15. PyQt:从GUI发送信息到线程
- 16. PyQt的多线程,不能为父母
- 17. pyqt:如何正确退出线程
- 18. 将值发送给工作线程PyQt?
- 19. PyQT线程最简单的方法
- 20. 保持PyQt UI响应线程
- 21. 与python pyqt一起使用线程?
- 22. 控制PyQt中的异步线程 - 多线程或多处理?
- 23. pyqt多线程 - 无法同时运行单独的线程?
- 24. 从python线程(不是主线程)启动pyQt线程有什么不好?
- 25. PyQt线程和信号 - 如何正确检索值
- 26. PyQt信号和插槽,线程之间传递对象
- 27. PyQt线程通信的帮助? QThread和QObject
- 28. 实时绘制Matplotlib,PyQt和线程结束python崩溃
- 29. PyQT线程和Socketing安全,并捕捉多个信号
- 30. PyQt线编辑颜色
你可能会发现这里的讨论:http://stackoverflow.com/questions/1595649/threading-in-a-pyqt-application -use-qt-threads-or-python-threads很有用,还有一些来自该问题的链接。 – jkerian 2010-10-01 19:55:26