先使用qtdesigner画两个按钮和两个text,用来检测功能。
在使用pyuic将其转换为py文件。
先给按钮2定义一个简单的函数,运行。
import thread_update
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import *
import sys, os
import time
class MyThreadUpdate(thread_update.Ui_MainWindow):
def __init__(self):
super(MyThreadUpdate, self).__init__()
def retranslateUi(self, MainWindow):
super(MyThreadUpdate, self).retranslateUi(MainWindow)
ui.pushButton_2.clicked.connect(self.buttonsec_clicked)
def buttonsec_clicked(self):
chr_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
for element in chr_list:
time.sleep(1)
print(element)
print('end')
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = MyThreadUpdate()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
会发现执行函数过程中UI界面卡死,如图所示:
可以通过qt的QThread来解决。代码如下:
import thread_update
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import *
import sys, os
import time
class ButtonOne(QThread):
def __init__(self):
super(ButtonOne, self).__init__()
def write(self, text):
self.signalForText.emit(text)
def run(self):
for i in range(15):
time.sleep(1)
print(i)
print('end')
class ButtonSec(QThread):
def __init__(self):
super(ButtonSec, self).__init__()
def run(self):
chr_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
for element in chr_list:
time.sleep(1)
print(element)
print('end')
class MyThreadUpdate(thread_update.Ui_MainWindow):
def __init__(self):
super(MyThreadUpdate, self).__init__()
self.thread_buttonsec = ButtonSec()
self.thread_buttonone = ButtonOne()
def retranslateUi(self, MainWindow):
super(MyThreadUpdate, self).retranslateUi(MainWindow)
ui.button_1.clicked.connect(self.buttonone_clicked)
ui.pushButton_2.clicked.connect(self.buttonsec_clicked)
def buttonone_clicked(self):
self.thread_buttonone.start()
def buttonsec_clicked(self):
self.thread_buttonsec.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = MyThreadUpdate()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
这样在点击按钮UI界面也不会卡顿。
下面实现将命令行输出重定向到UI界面上
import thread_update
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import *
import sys, os
import time
class ButtonOne(QThread):
_signalForText = pyqtSignal(str)
def __init__(self):
super(ButtonOne, self).__init__()
def write(self, text):
self.signalForText.emit(text)
def run(self):
for i in range(15):
time.sleep(1)
print(i)
print('end')
@property
def signalForText(self):
return self._signalForText
class ButtonSec(QThread):
def __init__(self):
super(ButtonSec, self).__init__()
def run(self):
chr_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
for element in chr_list:
time.sleep(1)
print(element)
print('end')
class MyThreadUpdate(thread_update.Ui_MainWindow):
def __init__(self):
super(MyThreadUpdate, self).__init__()
self.thread_buttonsec = ButtonSec()
self.thread_buttonone = ButtonOne()
self.thread_buttonone.signalForText.connect(self.updateText)
sys.stdout = self.thread_buttonone
def retranslateUi(self, MainWindow):
super(MyThreadUpdate, self).retranslateUi(MainWindow)
ui.button_1.clicked.connect(self.buttonone_clicked)
ui.pushButton_2.clicked.connect(self.buttonsec_clicked)
def updateText(self, text):
cursor = self.text_1.textCursor()
cursor.insertText(text)
self.text_1.setTextCursor(cursor)
self.text_1.ensureCursorVisible()
def buttonone_clicked(self):
self.thread_buttonone.start()
def buttonsec_clicked(self):
self.thread_buttonsec.start()
# chr_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# for element in chr_list:
# time.sleep(1)
# print(element)
# print('end')
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = MyThreadUpdate()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
如果想要在1按钮函数运行结束之前,按钮处于不可点击状态也可以通过信号实现。简略代码如下
button1函数部分在添加一个信号,并在函数执行结束之后在发射
class ButtonOne(QThread):
_signal = pyqtSignal()
_signalForText = pyqtSignal(str)
def __init__(self):
super(ButtonOne, self).__init__()
def write(self, text):
self.signalForText.emit(text)
def run(self):
for i in range(15):
time.sleep(1)
print(i)
print('end')
self._signal.emit()
@property
def signalForText(self):
return self._signalForText
UI界面部分代码,在点击按钮之后将按钮设为不可点击状态,同时在接收到信号时候将按钮设置为可以点击状态.
def buttonone_clicked(self):
self.button_1.setEnabled(False)
self.thread_buttonone.start()
self.thread_buttonone._signal.connect(self.enableButtonOne)
def enableButtonOne(self):
self.button_1.setEnabled(True)