Python 使用QThread更改QTextBrowser

Python 使用QThread更改QTextBrowser,python,pyqt5,qthread,Python,Pyqt5,Qthread,我正在尝试使用QTextBrowser显示一些数据。然而,它冻结,因为我没有以正确的方式使用线程。我在stackoverflow上搜索了一些QThread问题,但无法找出我的代码无法工作的原因 我想打印“Hello”五次,每次打印过程中都要睡眠1秒 我还想通过QLineEdit获取输入,以设置time.sleep(冷却时间),但我可以在解决Qthread问题后进行 我在代码中搜索并尝试实现的解决方案有: 可能我使用了错误的实现方法。但是我是个新手,请帮我 # -*- coding: utf-

我正在尝试使用QTextBrowser显示一些数据。然而,它冻结,因为我没有以正确的方式使用线程。我在stackoverflow上搜索了一些QThread问题,但无法找出我的代码无法工作的原因

我想打印“Hello”五次,每次打印过程中都要睡眠1秒

我还想通过QLineEdit获取输入,以设置time.sleep(冷却时间),但我可以在解决Qthread问题后进行

我在代码中搜索并尝试实现的解决方案有:

可能我使用了错误的实现方法。但是我是个新手,请帮我

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'denn.ui'
#
# Created by: PyQt5 UI code generator 5.12.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
from time import *

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        MainWindow.setStyleSheet("")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.lineEdit.setFont(font)
        self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout.addWidget(self.lineEdit)
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.textBrowser.setFont(font)
        self.textBrowser.setObjectName("textBrowser")
        self.verticalLayout.addWidget(self.textBrowser)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("QPushButton {\n"
"    color: white;\n"
"    border: 2px solid #46963f;\n"
"    border-radius: 20px;\n"
"    border-style: outset;\n"
"    /*background: qradialgradient(\n"
"        cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,\n"
"        radius: 1.35, stop: 0 #fff, stop: 1 #46963f\n"
"        );*/\n"
"    background:#46963f;\n"
"    padding: 5px;\n"
"    }\n"
"\n"
"QPushButton:hover {\n"
"    border: 2px solid #07121b;\n"
"    /*background: qradialgradient(\n"
"        cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,\n"
"        radius: 1.35, stop: 0 #fff, stop: 1 #1b486d\n"
"        );*/\n"
"    background: #1b486d;\n"
"    }\n"
"\n"
"QPushButton:pressed {\n"
"    border: 2px solid #07121b;\n"
"    border-style: inset;\n"
"    /*background: qradialgradient(\n"
"        cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1,\n"
"        radius: 1.35, stop: 0 #fff, stop: 1 #1b486d\n"
"        );*/\n"
"    background: #1b486d;\n"
"\n"
"    }")
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "Deneme Programı"))
        self.lineEdit.setPlaceholderText(_translate("MainWindow", "Bekleme Süresi"))
        self.pushButton.setText(_translate("MainWindow", "Başlat"))

        try:
            self.pushButton.clicked.connect(self.x)
        except Exception as e:
            print(e)

    def x(self):
        cd = int(self.lineEdit.text())
        for i in range(5):
            self.thread = DummyThread(self, cd)
            self.thread.start()
            self.thread.finished.connect(self.a)

    def a(self):
        self.textBrowser.setText(self.textBrowser.toPlainText() + "\nHello")

class DummyThread(QThread):
    finished = pyqtSignal()
    def __init__(self,cd):
        super(DummyThread, self).__init__()
        self.cd = cd
    def run(self):
        time.sleep(self.cd)
        self.finished.emit()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

DummyThread不接受任何参数,在创建实例时删除
self
。 由于从时间导入*中执行
,因此需要从
time.sleep(1)
中删除
time.
。 这将产生以下代码:

    def x(self):
        self.thread = DummyThread()
        self.thread.start()
        self.thread.finished.connect(self.a)
    def a(self):
        self.textBrowser.setText(self.textBrowser.toPlainText() + "\nHello")

class DummyThread(QThread):
    finished = pyqtSignal()
    def run(self):
        sleep(1)
        self.finished.emit()

p、 正如文件介绍所建议的,不建议向PyUIC生成的文件中添加代码。

您的代码失败的原因是因为它不是从QObject继承的。 要使QThread工作,父线程必须继承自
QObject
或非
对象的派生类

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'denn.ui'
#
# Created by: PyQt5 UI code generator 5.12.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
import time


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        MainWindow.setStyleSheet("")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.lineEdit.setFont(font)
        self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout.addWidget(self.lineEdit)
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.textBrowser.setFont(font)
        self.textBrowser.setObjectName("textBrowser")
        self.verticalLayout.addWidget(self.textBrowser)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Open Sans")
        font.setPointSize(20)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("QPushButton {\n"
"    color: white;\n"
"    border: 2px solid #46963f;\n"
"    border-radius: 20px;\n"
"    border-style: outset;\n"
"    /*background: qradialgradient(\n"
"        cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,\n"
"        radius: 1.35, stop: 0 #fff, stop: 1 #46963f\n"
"        );*/\n"
"    background:#46963f;\n"
"    padding: 5px;\n"
"    }\n"
"\n"
"QPushButton:hover {\n"
"    border: 2px solid #07121b;\n"
"    /*background: qradialgradient(\n"
"        cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,\n"
"        radius: 1.35, stop: 0 #fff, stop: 1 #1b486d\n"
"        );*/\n"
"    background: #1b486d;\n"
"    }\n"
"\n"
"QPushButton:pressed {\n"
"    border: 2px solid #07121b;\n"
"    border-style: inset;\n"
"    /*background: qradialgradient(\n"
"        cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1,\n"
"        radius: 1.35, stop: 0 #fff, stop: 1 #1b486d\n"
"        );*/\n"
"    background: #1b486d;\n"
"\n"
"    }")
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "Deneme Programı"))
        self.lineEdit.setPlaceholderText(_translate("MainWindow", "Bekleme Süresi"))
        self.pushButton.setText(_translate("MainWindow", "Başlat"))

        

class Window(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.pushButton.clicked.connect(self.x)
    def x(self):
        cd = int(self.ui.lineEdit.text())
        for i in range(5):
            self.thread = DummyThread(self, cd)
            self.thread.finished.connect(self.a)
            self.thread.start()

    def a(self):
        self.ui.textBrowser.setText(self.ui.textBrowser.toPlainText() + "\nHello")

class DummyThread(QThread):
    finished = pyqtSignal()
    def __init__(self, parent, cd):
        super(DummyThread, self).__init__(parent)
        self.cd = cd

    def run(self):
        time.sleep(self.cd)
        self.finished.emit()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec_())

代码中有3个问题

  • 您在线程构造函数中使用了两个参数(
    self,cd
    ),而DummyThread的
    \uuu init\uuu
    只接受一个参数。请注意,即使在init中添加
    parent
    参数,它也不会工作,因为QThread(因为所有QObject)只接受一个QObject实例作为父对象,而该范围内的
    self
    Ui\u主窗口
    实例(这是一个简单的python
    对象
  • 您使用了时间导入中的
    *
    ,因此不能使用
    time.sleep
    ,而是
    sleep
  • 您不断地覆盖
    self.thread
    实例,这意味着每次尝试使用相同的引用创建新实例时,前一个实例将立即被垃圾收集,这会导致崩溃,因为线程仍在处理时被销毁。请注意,即使您仅创建一个实例,然后在前一个实例仍处于活动状态时,或者如果没有对线程实例使用持久引用(因为函数返回后它将被销毁),尝试再次运行
    x
  • 因此,为了解决您的问题,您需要进行以下修改:

    class Ui\u主窗口(对象):
    def设置UI(自我,主窗口):
    # ...
    self.threads=[]
    def x(自我):
    cd=int(self.lineEdit.text())
    对于范围(5)中的i:
    线程=读取(cd)
    thread.start()
    线程.finished.connect(self.a)
    self.threads.append(线程)
    
    请注意,如果需要同时多次运行相同的处理,可以改用QRunnable。
    另外请注意,正如在另一个答案中所指出的,在文件开头和数百个其他问题中,您应该永远不要修改pyuic创建的文件(也不要尝试模仿它们的行为),原因之一是它可能会导致对象结构的混淆(与您的情况完全相同)。我建议您阅读官方指南中关于使用这些文件的正确方法的更多信息。

    您好,它没有给我任何错误,但也没有在每次睡眠后打印Hello。它在过程完成时打印。我想查看睡眠后的每一次打印我没有改变您的逻辑。如果您给它数字1,它将开始5更新gui之前,线程和睡眠1秒钟。所有这些线程都将并发运行(睡眠时)。