PyQt5 pyqt多線程操作入門
首先來看一個例子:
# coding=utf-8
__author__ = 'a359680405'
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
global sec
sec=0
def setTime():
global sec
sec+=1
lcdNumber.display(sec) #LED顯示數(shù)字+1
def work():
timer.start(1000) #計時器每秒計數(shù)
for i in range(2000000000):
pass
timer.stop()
app=QApplication([])
top=QWidget()
layout=QVBoxLayout(top) #垂直布局類QVBoxLayout;
lcdNumber=QLCDNumber() #加個顯示屏
layout.addWidget(lcdNumber)
button=QPushButton("測試")
layout.addWidget(button)
timer=QTimer()
timer.timeout.connect(setTime) #每次計時結束,觸發(fā)setTime
button.clicked.connect(work)
top.show()
app.exec()
我們的主界面有一個用于顯示時間的 LCD 數(shù)字面板還有一個用于啟動任務的按鈕。程序的目的是用戶點擊按鈕,開始一個非常耗時的運算(程序中我們以一個 2000000000 次的循環(huán)來替代這個非常耗時的工作,在真實的程序中,這可能是一個網(wǎng)絡訪問,可能是需要復制一個很大的文件或者其它任務),同時 LCD 開始顯示逝去的毫秒數(shù)。毫秒數(shù)通過一個計時器QTimer進行更新。計算完成后,計時器停止。這是一個很簡單的應用,也看不出有任何問題。但是當我們開始運行程序時,問題就來了:點擊按鈕之后,程序界面直接停止響應,直到循環(huán)結束才開始重新更新,于是計時器使用顯示0。
有經(jīng)驗的開發(fā)者立即指出,這里需要使用線程。這是因為 Qt 中所有界面都是在 UI 線程中(也被稱為主線程,就是執(zhí)行了QApplication::exec()的線程),在這個線程中執(zhí)行耗時的操作(比如那個循環(huán)),就會阻塞 UI 線程,從而讓界面停止響應。界面停止響應,用戶體驗自然不好,不過更嚴重的是,有些窗口管理程序會檢測到你的程序已經(jīng)失去響應,可能會建議用戶強制停止程序,這樣一來你的程序可能就此終止,任務再也無法完成。所以,為了避免這一問題,我們要使用 QThread 開啟一個新的線程:
# coding=utf-8
__author__ = 'a359680405'
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
global sec
sec=0
class WorkThread(QThread):
trigger = pyqtSignal()
def __int__(self):
super(WorkThread,self).__init__()
def run(self):
for i in range(203300030):
pass
self.trigger.emit() #循環(huán)完畢后發(fā)出信號
def countTime():
global sec
sec+=1
lcdNumber.display(sec) #LED顯示數(shù)字+1
def work():
timer.start(1000) #計時器每秒計數(shù)
workThread.start() #計時開始
workThread.trigger.connect(timeStop) #當獲得循環(huán)完畢的信號時,停止計數(shù)
def timeStop():
timer.stop()
print("運行結束用時",lcdNumber.value())
global sec
sec=0
app=QApplication([])
top=QWidget()
layout=QVBoxLayout(top) #垂直布局類QVBoxLayout;
lcdNumber=QLCDNumber() #加個顯示屏
layout.addWidget(lcdNumber)
button=QPushButton("測試")
layout.addWidget(button)
timer=QTimer()
workThread=WorkThread()
button.clicked.connect(work)
timer.timeout.connect(countTime) #每次計時結束,觸發(fā)setTime
top.show()
app.exec()
我增加了一個WorkerThread類。WorkerThread繼承自QThread類,重寫了其run()函數(shù)??梢哉J為,run()函數(shù)就是新的線程需要執(zhí)行的代碼。在這里就是要執(zhí)行這個循環(huán),然后發(fā)出計算完成的信號。而在按鈕點擊的槽函數(shù)中,使用work()中的workThread.start()函數(shù)啟動一個線程(注意,這里不是run()函數(shù))。再次運行程序,你會發(fā)現(xiàn)現(xiàn)在界面已經(jīng)不會被阻塞了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
對python中兩種列表元素去重函數(shù)性能的比較方法
今天小編就為大家分享一篇對python中兩種列表元素去重函數(shù)性能的比較方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06

