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

溫馨提示×

溫馨提示×

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

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

python GUI庫圖形界面開發之PyQt5線程類QThread詳細使用方法

發布時間:2020-08-27 06:01:10 來源:腳本之家 閱讀:484 作者:jia666666 欄目:開發技術

QThread是Qt的線程類中最核心的底層類。由于PyQt的的跨平臺特性,QThread要隱藏所有與平臺相關的代碼

要使用的QThread開始一個線程,可以創建它的一個子類,然后覆蓋其它QThread.run()函數

 class Thread(QThread):
  def __init __(self):
    super(Thread,self).__ init __()
  def run(self):
    #線程相關的代碼
    pass

接下來創建一個新的線程

thread = Thread()
thread.start()

可以看出,PyQt的線程使用非常簡單—-建立一個自定義的類(如thread),自我繼承自QThread ,并實現其run()方法即可

在使用線程時可以直接得到Thread實例,調用其start()函數即可啟動線程,線程啟動之后,會自動調用其實現的run()的函數,該方法就是線程的執行函數

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

QThread類中的常用方法

方法 描述
start() 啟動線程
wait() 阻止線程,直到滿足如下條件之一
與此QThread對象關聯的線程已完成執行(即從run返回時),如果線程完成執行,此函數返回True,如果線程尚未啟動,也返回True
等待時間的單位是毫秒,如果時間是ULONG_MAX(默認值·),則等待,永遠不會超時(線程必須從run返回),如果等待超時,此函數將會返回False
sleep() 強制當前線程睡眠多少秒

QThread類中的常用信號

信號 描述
started 在開始執行run函數之前,從相關線程發射此信號
finished 當程序完成業務邏輯時,從相關線程發射此信號

QThread的使用方法實例

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class MainWidget(QWidget):
  def __init__(self, parent=None):
    super(MainWidget, self).__init__(parent)
    #設置標題
    self.setWindowTitle('QThread多線程例子')

    #實例化多線程對象
    self.thread = Worker()

    #實例化列表控件與按鈕控件
    self.listFile = QListWidget()
    self.btnStart = QPushButton('開始')

    #把控件放置在柵格布局中
    layout = QGridLayout(self)
    layout.addWidget(self.listFile, 0, 0, 1, 2)
    layout.addWidget(self.btnStart, 1, 1)

    #信號與槽函數的連接
    self.btnStart.clicked.connect(self.slotStart)
    self.thread.sinOut.connect(self.slotAdd)

  def slotAdd(self, file_inf):
    #向列表控件中添加條目
    self.listFile.addItem(file_inf)

  def slotStart(self):
    #開始按鈕不可點擊,線程開始
    self.btnStart.setEnabled(False)
    self.thread.start()


class Worker(QThread):
  sinOut = pyqtSignal(str)

  def __init__(self, parent=None):
    super(Worker, self).__init__(parent)
    #設置工作狀態與初始num數值
    self.working = True
    self.num = 0

  def __del__(self):
    #線程狀態改變與線程終止
    self.working = False
    self.wait()

  def run(self):
    while self.working == True:
      #獲取文本
      file_str = 'File index{0}'.format(self.num)
      self.num += 1
      # 發射信號
      self.sinOut.emit(file_str)
      # 線程休眠2秒
      self.sleep(2)


if __name__ == '__main__':
  app = QApplication(sys.argv)
  demo = MainWidget()
  demo.show()
  sys.exit(app.exec_())

運行效果圖如下

python GUI庫圖形界面開發之PyQt5線程類QThread詳細使用方法

代碼分析

在這個例子中,單擊開始按鈕,會在后臺定時讀取數據,并把返回的數據顯示在界面中,首先使用以下代碼進行布局,把列表控件和按鈕控件放在柵格布局管理器中

#實例化列表控件與按鈕控件
self.listFile = QListWidget()
self.btnStart = QPushButton('開始')

#把控件放置在柵格布局中
layout = QGridLayout(self)
layout.addWidget(self.listFile, 0, 0, 1, 2)
layout.addWidget(self.btnStart, 1, 1)

然后將按鈕的clicked信號連接到槽函數,單擊開始觸發槽函數

self.btnStart.clicked.connect(self.slotStart)
def slotStart(self):
    #開始按鈕不可點擊,線程開始
    self.btnStart.setEnabled(False)
    self.thread.start()

比較復雜的是線程的信號,將線程的sinOut信號連接到slotAdd()槽函數,SlotAdd()函數負責在列表控件中動態添加字符串條目

self.thread.sinOut.connect(self.slotAdd)
def slotAdd(self,file_inf):
    #向列表控件中添加條目
    self.listFile.addItem(file_inf)

定義一個線程類,繼承自QThread,當線程啟動時,執行run()函數

class Worker(QThread):
  sinOut = pyqtSignal(str)

  def __init__(self, parent=None):
    super(Worker, self).__init__(parent)
    #設置工作狀態與初始num數值
    self.working = True
    self.num = 0

  def __del__(self):
    #線程狀態改變與線程終止
    self.working = False
    self.wait()

  def run(self):
    while self.working == True:
      #獲取文本
      file_str = 'File index{0}'.format(self.num)
      self.num += 1
      # 發射信號
      self.sinOut.emit(file_str)
      # 線程休眠2秒
      self.sleep(2)

多線程失敗案例

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

global sec
sec=0

def setTime():
  global sec
  sec+=1
  #Led顯示數字+1
  lcdNumber.display(sec)

def work():
  #計時器每秒計數
  timer.start(1000)
  for i in range(200000000):
    pass
  timer.stop()
if __name__ == '__main__':
  app=QApplication(sys.argv)
  top=QWidget()
  top.resize(300,120)

  #垂直布局
  layout=QVBoxLayout(top)
  #添加一個顯示面板
  lcdNumber=QLCDNumber()
  layout.addWidget(lcdNumber)
  button=QPushButton('測試')
  layout.addWidget(button)

  timer=QTimer()
  #每次計時結束,觸發setTime
  timer.timeout.connect(setTime)
  button.clicked.connect(work)

  top.show()
  sys.exit(app.exec_())

失敗效果圖如下

python GUI庫圖形界面開發之PyQt5線程類QThread詳細使用方法

長時間停留在此界面,知道多線程任務完成后,此界面才會動,當耗時程序非常大時,就會造成程序運行失敗的假象,實際還是在后臺運行的,只是沒有顯示在主窗口的界面上,當然用戶體驗也就非常差,那么如何解決這個問題呢,下面實例三進行解答

分離UI主線程與工作線程實例

import sys
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(2000000000):
      pass

    # 循環完畢后發出信號
    self.trigger.emit()


def countTime():
  global sec
  sec += 1
  # LED顯示數字+1
  lcdNumber.display(sec)


def work():
  # 計時器每秒計數
  timer.start(1000)
  # 計時開始
  workThread.start()
  # 當獲得循環完畢的信號時,停止計數
  workThread.trigger.connect(timeStop)


def timeStop():
  #定時器停止
  timer.stop()
  print("運行結束用時", lcdNumber.value())
  global sec
  sec = 0


if __name__ == "__main__":
  app = QApplication(sys.argv)
  top = QWidget()
  top.resize(300, 120)

  # 垂直布局類QVBoxLayout
  layout = QVBoxLayout(top)

  # 加顯示屏,按鈕到布局中
  lcdNumber = QLCDNumber()
  layout.addWidget(lcdNumber)
  button = QPushButton("測試")
  layout.addWidget(button)

  #實例化定時器與多線程類
  timer = QTimer()
  workThread = WorkThread()

  button.clicked.connect(work)
  # 每次計時結束,觸發 countTime
  timer.timeout.connect(countTime)

  top.show()
  sys.exit(app.exec_())

運行效果,程序主界面的數值會每秒增加1,直到循環結束,這里就避免了主界面長時間不動的尷尬!

python GUI庫圖形界面開發之PyQt5線程類QThread詳細使用方法

QThread線程事件處理實例

對于執行很耗時的程序來說,由于PyQt需要等待程序執行完畢才能進行下一步,這個過程表現在界面上就是卡頓,而如果需要執行這個耗時程序時不斷的刷新界面。那么就可以使用QApplication.processEvents(),那么就可以一邊執行耗時程序,一邊刷新界面的功能,給人的感覺就是程序運行很流暢,因此QApplicationEvents()的使用方法就是,在主函數執行耗時操作的地方,加入QApplication.processEvents()

import sys,time
from PyQt5.QtWidgets import QWidget,QPushButton,QApplication,QListWidget,QGridLayout

class WinForm(QWidget):
  def __init__(self,parent=None):
    super(WinForm, self).__init__(parent)
    #設置標題與布局方式
    self.setWindowTitle('實時刷新界面的例子')
    layout=QGridLayout()

    #實例化列表控件與按鈕控件
    self.listFile=QListWidget()
    self.btnStart=QPushButton('開始')

    #添加到布局中指定位置
    layout.addWidget(self.listFile,0,0,1,2)
    layout.addWidget(self.btnStart,1,1)

    #按鈕的點擊信號觸發自定義的函數
    self.btnStart.clicked.connect(self.slotAdd)
    self.setLayout(layout)
  def slotAdd(self):
    for n in range(10):
      #獲取條目文本
      str_n='File index{0}'.format(n)
      #添加文本到列表控件中
      self.listFile.addItem(str_n)
      #實時刷新界面
      QApplication.processEvents()
      #睡眠一秒
      time.sleep(1)
if __name__ == '__main__':
  app=QApplication(sys.argv)
  win=WinForm()
  win.show()
  sys.exit(app.exec_())

python GUI庫圖形界面開發之PyQt5線程類QThread詳細使用方法

本文詳細介紹了python GUI庫PyQt5的線程類QThread詳細使用方法,想了解更多相關知道請查看下面的相關鏈接

向AI問一下細節

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

AI

杭锦后旗| 陇西县| 烟台市| 罗源县| 平原县| 即墨市| 商丘市| 保德县| 洛扎县| 池州市| 青铜峡市| 潮安县| 通河县| 南充市| 石城县| 霍城县| 巩义市| 瓮安县| 化德县| 蕲春县| 吴忠市| 鄂温| 手游| 阜阳市| 阳泉市| 盖州市| 盱眙县| 新野县| 南靖县| 余江县| 张家港市| 团风县| 固阳县| 固原市| 通海县| 威远县| 巫溪县| 呼伦贝尔市| 巨鹿县| 梨树县| 比如县|