pyqt5?子線程如何操作主線程GUI(示例代碼)
一.簡(jiǎn)介
在使用pyqt5編寫(xiě)gui時(shí)遇到兩個(gè)問(wèn)題,會(huì)導(dǎo)致界面崩潰,今天就圍繞這兩個(gè)問(wèn)題來(lái)簡(jiǎn)單說(shuō)明和改進(jìn)。
1.在主線程中使用while無(wú)限循環(huán)會(huì)導(dǎo)致界面崩潰
2.在子線程中操作主線程gui會(huì)導(dǎo)致界面崩潰
二.步驟說(shuō)明
1.在主線程中使用while無(wú)限循環(huán)會(huì)導(dǎo)致界面崩潰
1)錯(cuò)誤代碼
import sys
from PyQt5.QtWidgets import QPushButton, QTextEdit, QApplication, QHBoxLayout, QWidget
class FileChooserApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
button = QPushButton("按鈕")
self.reviewEdit = QTextEdit()
self.reviewEdit.move(100, 100)
button.clicked.connect(self.send)
hbox1 = QHBoxLayout() # 創(chuàng)建一個(gè)水平布局
hbox1.addWidget(button) # 添加按鈕到水平布局中
hbox1.addStretch(1) # 設(shè)置水平比例間距
hbox1.addWidget(self.reviewEdit) # 添加按鈕到水平布局中
self.setLayout(hbox1) # 添加到布局器
self.setWindowTitle('文件選擇器')
self.setGeometry(300, 300, 500, 500)
def send(self):
"""
事件
:return:
"""
while True:
"""
邏輯代碼
"""
self.reviewEdit.setText("測(cè)試")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = FileChooserApp()
ex.show()
sys.exit(app.exec_())2)崩潰原因
我們先來(lái)說(shuō)下while崩潰的問(wèn)題,這邊我設(shè)置的循環(huán)是一個(gè)無(wú)限循環(huán),不會(huì)給 GUI 事件循環(huán)任何運(yùn)行的機(jī)會(huì)。在 PyQt 或其他 GUI 框架中,GUI 的事件循環(huán)(例如按鈕點(diǎn)擊、窗口移動(dòng)等)必須在單獨(dú)的線程中運(yùn)行,以保持 GUI 的響應(yīng)性
3)改進(jìn)方法
將循環(huán)體在一個(gè)子線程中執(zhí)行,就可以避免這個(gè)問(wèn)題,代碼如下。
import sys
import threading
from PyQt5.QtWidgets import QPushButton, QTextEdit, QApplication, QHBoxLayout, QWidget
class FileChooserApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
button = QPushButton("按鈕")
self.reviewEdit = QTextEdit()
self.reviewEdit.move(100, 100)
button.clicked.connect(self.send)
hbox1 = QHBoxLayout() # 創(chuàng)建一個(gè)水平布局
hbox1.addWidget(button) # 添加按鈕到水平布局中
hbox1.addStretch(1) # 設(shè)置水平比例間距
hbox1.addWidget(self.reviewEdit) # 添加按鈕到水平布局中
self.setLayout(hbox1) # 添加到布局器
self.setWindowTitle('文件選擇器')
self.setGeometry(300, 300, 500, 500)
def send(self):
"""
事件
:return:
"""
def send_a():
while True:
"""
邏輯代碼
"""
print("123")
send_thread = threading.Thread(target=send_a)
# 啟動(dòng)線程
send_thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = FileChooserApp()
ex.show()
sys.exit(app.exec_())2.在子線程中操作主線程gui會(huì)導(dǎo)致界面崩潰
1)錯(cuò)誤代碼
import sys
import threading
import time
from PyQt5.QtWidgets import QPushButton, QTextEdit, QApplication, QHBoxLayout, QWidget
class FileChooserApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
button = QPushButton("按鈕")
self.reviewEdit = QTextEdit()
self.reviewEdit.move(100, 100)
button.clicked.connect(self.send)
hbox1 = QHBoxLayout() # 創(chuàng)建一個(gè)水平布局
hbox1.addWidget(button) # 添加按鈕到水平布局中
hbox1.addStretch(1) # 設(shè)置水平比例間距
hbox1.addWidget(self.reviewEdit) # 添加按鈕到水平布局中
self.setLayout(hbox1) # 添加到布局器
self.setWindowTitle('文件選擇器')
self.setGeometry(300, 300, 500, 500)
def send(self):
"""
事件
:return:
"""
def send_a():
while True:
"""
邏輯代碼
"""
self.reviewEdit.setText("設(shè)置文案")
send_thread = threading.Thread(target=send_a)
# 啟動(dòng)線程
send_thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = FileChooserApp()
ex.show()
sys.exit(app.exec_())2)崩潰原因
上述中試圖在子線程send_a方法中給文本編輯器設(shè)置文案。這是不允許的,因?yàn)?PyQt 和大多數(shù) GUI 框架一樣,要求所有的 GUI 更新必須在主線程(也稱為 GUI 線程)中執(zhí)行。
3)改進(jìn)方法
既然在子線程中無(wú)法操作主線程gui更新,那么只能在主線程中去執(zhí)行,這就需要信號(hào)與槽的配合了。我們先來(lái)自定義一個(gè)信號(hào)
class YourThread(QObject):
show_warning_signal = pyqtSignal()
def run(self):
self.show_warning_signal.emit()在初始化的時(shí)候去實(shí)例化YourThread類(lèi),連線信號(hào)與槽
class FileChooserApp(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.your = YourThread()
self.your.show_warning_signal.connect(self.settext)接著在子線程中直接去觸發(fā)信號(hào)即可
def send(self):
def send_a():
while True:
"""
循環(huán)體
"""
self.your.run()
time.sleep(2)
send_thread = threading.Thread(target=send_a)
# 啟動(dòng)線程
send_thread.start()執(zhí)行每次循環(huán)需要等待2s,避免出現(xiàn)無(wú)限循環(huán)導(dǎo)致應(yīng)用程序凍結(jié)、響應(yīng)緩慢或其他線程相關(guān)的問(wèn)題
三.實(shí)例
import sys
import threading
import time
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QPushButton, QTextEdit, QApplication, QHBoxLayout, QWidget
class YourThread(QObject):
show_warning_signal = pyqtSignal()
def run(self):
self.show_warning_signal.emit()
class FileChooserApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.your = YourThread()
self.your.show_warning_signal.connect(self.settext)
def initUI(self):
button = QPushButton("按鈕")
self.reviewEdit = QTextEdit()
self.reviewEdit.move(100, 100)
button.clicked.connect(self.send)
hbox1 = QHBoxLayout() # 創(chuàng)建一個(gè)水平布局
hbox1.addWidget(button) # 添加按鈕到水平布局中
hbox1.addStretch(1) # 設(shè)置水平比例間距
hbox1.addWidget(self.reviewEdit) # 添加按鈕到水平布局中
self.setLayout(hbox1) # 添加到布局器
self.setWindowTitle('文件選擇器')
self.setGeometry(300, 300, 500, 500)
def send(self):
"""
事件
:return:
"""
def send_a():
while True:
"""
邏輯代碼
"""
self.your.run()
time.sleep(2)
send_thread = threading.Thread(target=send_a)
# 啟動(dòng)線程
send_thread.start()
def settext(self):
self.reviewEdit.setText("123")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = FileChooserApp()
ex.show()
sys.exit(app.exec_())到此這篇關(guān)于pyqt5 子線程如何操作主線程GUI的文章就介紹到這了,更多相關(guān)pyqt5 子線程操作主線程GUI內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PyTorch使用Tricks:Dropout,R-Dropout和Multi-Sample?Dropout方式
這篇文章主要介紹了PyTorch使用Tricks:Dropout,R-Dropout和Multi-Sample?Dropout方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
Python實(shí)現(xiàn)訪問(wèn)者模式詳情
這篇文章主要介紹了Python實(shí)現(xiàn)訪問(wèn)者模式詳情,訪問(wèn)者模式,指作用于一個(gè)對(duì)象結(jié)構(gòu)體上的元素的操作。訪問(wèn)者可以使用戶在不改變?cè)摻Y(jié)構(gòu)體中的類(lèi)的基礎(chǔ)上定義一個(gè)新的操作,下文更多相關(guān)資料,需要的朋友可以參考下2022-03-03
python自動(dòng)提取文本中的時(shí)間(包含中文日期)
這篇文章主要介紹了python自動(dòng)提取文本中的時(shí)間(包含中文日期),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
使用pytorch提取卷積神經(jīng)網(wǎng)絡(luò)的特征圖可視化
這篇文章主要給大家介紹了關(guān)于使用pytorch提取卷積神經(jīng)網(wǎng)絡(luò)的特征圖可視化的相關(guān)資料,文中給出了詳細(xì)的思路以及示例代碼,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-03-03
python學(xué)生信息管理系統(tǒng)實(shí)現(xiàn)代碼
這篇文章主要介紹了python學(xué)生信息管理系統(tǒng)的實(shí)現(xiàn)代碼,代碼簡(jiǎn)單,復(fù)制即可使用,需要的朋友可以參考下2019-12-12
Python利用PyPDF2庫(kù)處理PDF文件的基本操作
PyPDF2是一個(gè)Python庫(kù),用于處理PDF文件,包括合并、分割、旋轉(zhuǎn)和提取文本等操作,它是一個(gè)功能強(qiáng)大且靈活的工具,可用于自動(dòng)化處理PDF文件,適用于各種應(yīng)用,從文檔管理到數(shù)據(jù)分析,本文將深入介紹PyPDF2庫(kù),掌握如何利用它來(lái)處理PDF文件,需要的朋友可以參考下2023-11-11
pandas 數(shù)據(jù)索引與選取的實(shí)現(xiàn)方法
這篇文章主要介紹了pandas 數(shù)據(jù)索引與選取的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

