PyQt 多线程基础学习

PyQt 多线程基础学习,第1张

1,基础案例

先来看段代码。功能是按下Button 1的时候控制台打印1-100,同时lineEdit 1也显示1-100,每隔1秒打印显示一次;按下Button 2的时候控制台打印100-1,同时lineEdit 2也显示100-1,每隔1秒打印显示一次。然而当实际按下按钮1时,控制台确实在打印,然而gui却卡死了,lineEdit也无法显示。

import sys
import time

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QThread")
        self.resize(300, 400)
        self.widget = QWidget()
        self.setCentralWidget(self.widget)
        self.layout = QtWidgets.QVBoxLayout(self.widget)
        self.lineEdit1 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit1.setObjectName("lineEdit1")
        self.pushButton1 = QtWidgets.QPushButton(self.widget)
        self.pushButton1.setObjectName("pushButton1")
        self.pushButton1.setText("Button 1")
        self.lineEdit2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit2.setObjectName("lineEdit2")
        self.pushButton2 = QtWidgets.QPushButton(self.widget)
        self.pushButton2.setObjectName("pushButton2")
        self.pushButton2.setText("Button 2")
        self.layout.addWidget(self.lineEdit1)
        self.layout.addWidget(self.pushButton1)
        self.layout.addWidget(self.lineEdit2)
        self.layout.addWidget(self.pushButton2)
        QtCore.QMetaObject.connectSlotsByName(self)

    @pyqtSlot()
    def on_pushButton1_clicked(self):
        for i in range(100):
            self.lineEdit1.setText(str(i))
            print(i)
            time.sleep(1)

    @pyqtSlot()
    def on_pushButton2_clicked(self):
        for i in range(100):
            self.lineEdit1.setText(str(100-i))
            print(100 - i)
            time.sleep(1)


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

2,QThread解决方案

单独实现控制台打印很简答,增加两个QThread子类,当按下按钮时创建并运行子类的run方法即可。注意thread1和thread2需要定义为实例属性,不要定义为局部变量。

import sys
import time

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSlot, QThread
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QThread")
        self.resize(300, 400)
        self.widget = QWidget()
        self.setCentralWidget(self.widget)
        self.layout = QtWidgets.QVBoxLayout(self.widget)
        self.lineEdit1 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit1.setObjectName("lineEdit1")
        self.pushButton1 = QtWidgets.QPushButton(self.widget)
        self.pushButton1.setObjectName("pushButton1")
        self.pushButton1.setText("Button 1")
        self.lineEdit2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit2.setObjectName("lineEdit2")
        self.pushButton2 = QtWidgets.QPushButton(self.widget)
        self.pushButton2.setObjectName("pushButton2")
        self.pushButton2.setText("Button 2")
        self.layout.addWidget(self.lineEdit1)
        self.layout.addWidget(self.pushButton1)
        self.layout.addWidget(self.lineEdit2)
        self.layout.addWidget(self.pushButton2)
        QtCore.QMetaObject.connectSlotsByName(self)

    @pyqtSlot()
    def on_pushButton1_clicked(self):
        self.thread1 = QThread1()
        self.thread1.start()

    @pyqtSlot()
    def on_pushButton2_clicked(self):
        self.thread2 = QThread2()
        self.thread2.start()


class QThread1(QThread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(100):
            print(i)
            time.sleep(1)


class QThread2(QThread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(100):
            print(100 - i)
            time.sleep(1)


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

如果需要实现按下按钮后lineEdit同时显示。有两种方法:
(1)将lineEdit对象传给QThread,然后在run方法里设置文本。

import sys
import time

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSlot, QThread
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QThread")
        self.resize(300, 400)
        self.widget = QWidget()
        self.setCentralWidget(self.widget)
        self.layout = QtWidgets.QVBoxLayout(self.widget)
        self.lineEdit1 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit1.setObjectName("lineEdit1")
        self.pushButton1 = QtWidgets.QPushButton(self.widget)
        self.pushButton1.setObjectName("pushButton1")
        self.pushButton1.setText("Button 1")
        self.lineEdit2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit2.setObjectName("lineEdit2")
        self.pushButton2 = QtWidgets.QPushButton(self.widget)
        self.pushButton2.setObjectName("pushButton2")
        self.pushButton2.setText("Button 2")
        self.layout.addWidget(self.lineEdit1)
        self.layout.addWidget(self.pushButton1)
        self.layout.addWidget(self.lineEdit2)
        self.layout.addWidget(self.pushButton2)
        QtCore.QMetaObject.connectSlotsByName(self)

    @pyqtSlot()
    def on_pushButton1_clicked(self):
        self.thread1 = QThread1(self.lineEdit1)
        self.thread1.start()

    @pyqtSlot()
    def on_pushButton2_clicked(self):
        self.thread2 = QThread2(self.lineEdit2)
        self.thread2.start()


class QThread1(QThread):
    def __init__(self, lineEdit):
        super().__init__()
        self.lineEdit = lineEdit

    def run(self):
        for i in range(100):
            self.lineEdit.setText(str(i))
            print(i)
            time.sleep(1)


class QThread2(QThread):
    def __init__(self, lineEdit):
        super().__init__()
        self.lineEdit = lineEdit

    def run(self):
        for i in range(100):
            self.lineEdit.setText(str(100 -i))
            print(100 - i)
            time.sleep(1)


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

(2)在QThread里定义信号,run方法里发射信号。信号和lineEdit的setText方法关联

import sys
import time

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSlot, QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QThread")
        self.resize(300, 400)
        self.widget = QWidget()
        self.setCentralWidget(self.widget)
        self.layout = QtWidgets.QVBoxLayout(self.widget)
        self.lineEdit1 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit1.setObjectName("lineEdit1")
        self.pushButton1 = QtWidgets.QPushButton(self.widget)
        self.pushButton1.setObjectName("pushButton1")
        self.pushButton1.setText("Button 1")
        self.lineEdit2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit2.setObjectName("lineEdit2")
        self.pushButton2 = QtWidgets.QPushButton(self.widget)
        self.pushButton2.setObjectName("pushButton2")
        self.pushButton2.setText("Button 2")
        self.layout.addWidget(self.lineEdit1)
        self.layout.addWidget(self.pushButton1)
        self.layout.addWidget(self.lineEdit2)
        self.layout.addWidget(self.pushButton2)
        QtCore.QMetaObject.connectSlotsByName(self)

    @pyqtSlot()
    def on_pushButton1_clicked(self):
        self.thread1 = QThread1()
        self.thread1.sg[str].connect(self.lineEdit1.setText)
        self.thread1.start()

    @pyqtSlot()
    def on_pushButton2_clicked(self):
        self.thread2 = QThread2()
        self.thread2.sg[str].connect(self.lineEdit2.setText)
        self.thread2.start()


class QThread1(QThread):
    sg = pyqtSignal(str)
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(100):
            self.sg[str].emit(str(i))
            print(i)
            time.sleep(1)


class QThread2(QThread):
    sg = pyqtSignal(str)
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(100):
            self.sg[str].emit(str(100 - i))
            print(100 - i)
            time.sleep(1)


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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/722580.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-26
下一篇2022-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存