我正在開發一個應用程序,它使用多個線程從各種網絡設備收集數據。我使用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中的線程化
- 5. PyQt線程屬性錯誤
- 6. PyQt信號跨線程
- 7. PyQt的多線程例子
- 8. 線程化函數-PyQt GUI
- 9. 應用程序線程和Qt線程之間的清晰分離(Python-PyQt)
- 10. PyQT線程最簡單的方法
- 11. 保持PyQt UI響應線程
- 12. pyqt:如何正確退出線程
- 13. 將值發送給工作線程PyQt?
- 14. 與python pyqt一起使用線程?
- 15. PyQt的多線程,不能爲父母
- 16. pyqt多線程 - 無法同時運行單獨的線程?
- 17. 從python線程(不是主線程)啓動pyQt線程有什麼不好?
- 18. PyQt信號和插槽,線程之間傳遞對象
- 19. PyQT線程和Socketing安全,並捕捉多個信號
- 20. PyQt線程通信的幫助? QThread和QObject
- 21. PyQt線程和信號 - 如何正確檢索值
- 22. PyQt線編輯顏色
- 23. GUI編程Pyqt
- 24. Stackless Python和PyQt
- 25. Wxwidgets和Pyqt
- 26. Boost.Python和PyQt
- 27. videocapture和pyqt
- 28. Ctypes和PyQt
- 29. PyQt和Python 2.5
- 30. 我可以強制matplotlib在PyQt線程/進程中阻塞嗎?
你可能會發現這裏的討論:http://stackoverflow.com/questions/1595649/threading-in-a-pyqt-application -use-qt-threads-or-python-threads很有用,還有一些來自該問題的鏈接。 – jkerian 2010-10-01 19:55:26