91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PyQt5中如何使用QThread多線程模塊

發布時間:2021-08-09 16:58:00 來源:億速云 閱讀:181 作者:Leah 欄目:編程語言

PyQt5中如何使用QThread多線程模塊,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

PyQt程序卡頓和無法實時顯示問題現象

使用PyQt界面程序,點擊運行按鈕后,程序在顯示框中每秒打印1個數字。程序代碼如下:

# -*- coding: utf-8 -*-import sysimport timefrom PyQt5.QtCore import QThread, pyqtSignalfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom QThread_Example_UI import Ui_Formclass MyMainForm(QMainWindow, Ui_Form):  def __init__(self, parent=None):    super(MyMainForm, self).__init__(parent)    self.setupUi(self)    self.runButton.clicked.connect(self.display)  def display(self):    for i in range(20):      time.sleep(1)      self.listWidget.addItem(str(i))if __name__ == "__main__":  app = QApplication(sys.argv)  myWin = MyMainForm()  myWin.show()  sys.exit(app.exec_())

程序運行過程結果如下(點擊Run按鈕后界面出現 未響應 字樣 同時程序也沒有出現每隔1秒打印1個數字,實際結果是循環結束后20個數字一同展示):

問題分析

上述實現的GUI程序都是單線程運行,對于需要執行一個特別耗時的操作時就會出現該問題現象。要解決這種問題可以考慮使用多線程模塊QThread。

多線程模塊QThread基本原理

QThread是Qt的線程類中最核心的底層類。由于PyQt的的跨平臺特性,QThread要隱藏所有與平臺相關的代碼要使用的QThread開始一個線程,可以創建它的一個子類,然后覆蓋其它QThread.run()函數。

class Thread(QThread):  def __init__(self):    super(Thread,self).__init__()  def run(self):    #

接下來創建一個新的線程

thread = Thread()thread.start()

可以看出,PyQt的線程使用非常簡單,建立一個自定義的類(如Thread),自我繼承自QThread ,并實現其run()方法即可。在使用線程時可以直接得到Thread實例,調用其start()函數即可啟動線程,線程啟動之后,會自動調用其實現的run()的函數,該方法就是線程的執行函數 。

業務的線程任務就寫在run()函數中,當run()退出之后線程就基本結束了,QThread有started和finished信號,可以為這兩個信號指定槽函數,在線程啟動和結束之時執行一段代碼進行資源的初始化和釋放操作,更靈活的使用方法是,在自定義的QThread實例中自定義信號,并將信號連接到指定的槽函數,當滿足一定的業務條件時發射此信號。

QThread類中的常用方法

start():啟動線程

wait():阻止線程,直到滿足如下條件之一

(1)與此QThread對象關聯的線程已完成執行(即從run返回時),如果線程完成執行,此函數返回True,如果線程尚未啟動,也返回True

(2)等待時間的單位是毫秒,如果時間是ULONG_MAX(默認值·),則等待,永遠不會超時(線程必須從run返回),如果等待超時,此函數將會返回False

sleep():強制當前線程睡眠多少秒

QThread類中的常用信號

started: 在開始執行run函數之前,從相關線程發射此信號

finished:當程序完成業務邏輯時,從相關線程發射此信號

使用QThread重新實現程序解決問題

先繼承QThread類并重新實現其中的run()函數,也就是說把耗時的操作放入run()函數中。代碼如下:

# -*- coding: utf-8 -*-import sysimport timefrom PyQt5.QtCore import QThread, pyqtSignalfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom QThread_Example_UI import Ui_Formclass MyMainForm(QMainWindow, Ui_Form):  def __init__(self, parent=None):    super(MyMainForm, self).__init__(parent)    self.setupUi(self)    # 實例化線程對象    self.work = WorkThread()    self.runButton.clicked.connect(self.execute)  def execute(self):    # 啟動線程    self.work.start()    # 線程自定義信號連接的槽函數    self.work.trigger.connect(self.display)  def display(self,str):    # 由于自定義信號時自動傳遞一個字符串參數,所以在這個槽函數中要接受一個參數    self.listWidget.addItem(str)class WorkThread(QThread):  # 自定義信號對象。參數str就代表這個信號可以傳一個字符串  trigger = pyqtSignal(str)  def __int__(self):    # 初始化函數    super(WorkThread, self).__init__()  def run(self):    #重寫線程執行的run函數    #觸發自定義信號    for i in range(20):      time.sleep(1)      # 通過自定義信號把待顯示的字符串傳遞給槽函數      self.trigger.emit(str(i))if __name__ == "__main__":  app = QApplication(sys.argv)  myWin = MyMainForm()  myWin.show()  sys.exit(app.exec_())

程序運行結果如下(實現了每隔1秒打印1個數字):

小結

如果你實現的工具需要執行特別耗時的操作,可以參考使用本文多線程QThread處理方法實現。當然,工具實際實現過程中的場景會比這復雜。比如,你的輸出并不是有固定時間間隔輸出的文本框,可以嘗試使用多次self.trigger.emit(str)方法進行操作。

附錄

1、使用pyuic5轉換界面.ui程序后的QThread_Example_UI.py代碼如下:

# -*- coding: utf-8 -*-from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):  def setupUi(self, Form):    Form.setObjectName("Form")    Form.resize(498, 331)    self.runButton = QtWidgets.QPushButton(Form)    self.runButton.setGeometry(QtCore.QRect(190, 30, 75, 23))    self.runButton.setObjectName("runButton")    self.listWidget = QtWidgets.QListWidget(Form)    self.listWidget.setGeometry(QtCore.QRect(30, 70, 431, 192))    self.listWidget.setObjectName("listWidget")    self.retranslateUi(Form)    QtCore.QMetaObject.connectSlotsByName(Form)  def retranslateUi(self, Form):    _translate = QtCore.QCoreApplication.translate    Form.setWindowTitle(_translate("Form", "Qthread Example"))    self.runButton.setText(_translate("Form", "Run"))

2、Qtdesigner設計的界面源程序代碼QThread_Example_UI.ui如下:

<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"> <class>Form</class> <widget class="QWidget" name="Form"> <property name="geometry">  <rect>  <x>0</x>  <y>0</y>  <width>498</width>  <height>331</height>  </rect> </property> <property name="windowTitle">  <string>Qthread Example</string> </property> <widget class="QPushButton" name="runButton">  <property name="geometry">  <rect>   <x>190</x>   <y>30</y>   <width>75</width>   <height>23</height>  </rect>  </property>  <property name="text">  <string>Run</string>  </property> </widget> <widget class="QListWidget" name="listWidget">  <property name="geometry">  <rect>   <x>30</x>   <y>70</y>   <width>431</width>   <height>192</height>  </rect>  </property> </widget> </widget> <resources/> <connections/></ui>

看完上述內容,你們掌握PyQt5中如何使用QThread多線程模塊的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兰州市| 伽师县| 娱乐| 即墨市| 绥阳县| 甘孜| 息烽县| 荔浦县| 新建县| 灵寿县| 冕宁县| 北海市| 枞阳县| 师宗县| 潞城市| 海丰县| 饶阳县| 无为县| 汤阴县| 绿春县| 共和县| 赤城县| 崇义县| 彭泽县| 资阳市| 长宁县| 凌云县| 泸溪县| 昌乐县| 阳朔县| 泰安市| 福鼎市| 太原市| 商南县| 永春县| 襄汾县| 隆德县| 临海市| 嘉峪关市| 新兴县| 丰宁|