关于pyqt5中QThread的问题

关于pyqt5中QThread的问题

img

这一列数字对应前一列分别进行倒计时

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTableWidget,QTableWidgetItem

import time 
from PyQt5.QtCore import QThread,pyqtSignal,QTimer


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(500, 625)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(10, 0, 75, 23))
        self.pushButton.setObjectName("pushButton")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1108, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.biaoge = QTableWidget(self.centralwidget)
        self.biaoge.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)#表格不可编辑
        # self.table.setRowCount(5)
        self.biaoge.setColumnCount(3)
        self.biaoge.setGeometry(10,40,480,550)
        self.biaoge.setColumnWidth(6,240)
        self.biaoge.setColumnWidth(7,300)
        self.biaoge.setRowCount(1)

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "开始"))

        self.biaoge.setHorizontalHeaderLabels(['1', '2', '3'])
        self.pushButton.clicked.connect(lambda:self.Start())

    def Start(self):
        self.starts = []
        

        list1 = [516,186,161]
        self.biaoge.setRowCount(len(list1))
        for x in range(0,len(list1)):
            self.starts.append(qthraed())
            for l in range(0,2):

                newItem = QTableWidgetItem(str(list1[x]))
                self.biaoge.setItem(x,l,newItem)
                self.starts[x].num = list1[x]
                self.starts[x].start()
                self.starts[x].sinOut.connect(self.outText)
    def outText(self, text): 
        newItem = QTableWidgetItem(text)
        self.biaoge.setItem(0,1,newItem)#这里就随便写了一下,不知道怎么实现

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

        def __init__(self, parent=None):
            super(qthraed, self).__init__(parent)
            self.Tist = True
            self.num = 0
        def __del__(self):
            self.Tist = False
            self.wait()

        def run(self):
            
            while True:
                self.num -= 1
                time.sleep(1)
                self.sinOut.emit(str(self.num))
                if self.num < 0:
                    break
                 
                # break

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_())


该回答引用ChatGPT,如果有帮助到您请点个采纳
稍微看了一下你的代码将每个时间值分配给单独的QThread,这不是一个很好的做法。
你可以应该考虑将所有时间值放入一个列表中,并使用一个线程来处理所有时间值。

也还可以通过使用QTimer来避免使用多个线程。

下面是一个更好的解决方案:


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem
import time 
from PyQt5.QtCore import QThread, pyqtSignal, QTimer

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(500, 625)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(10, 0, 75, 23))
        self.pushButton.setObjectName("pushButton")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1108, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.biaoge = QTableWidget(self.centralwidget)
        self.biaoge.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
        self.biaoge.setColumnCount(3)
        self.biaoge.setGeometry(10,40,480, 550)
        self.biaoge.setColumnWidth(0,240)
        self.biaoge.setColumnWidth(1,300)

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "开始"))

       

我需要每行单独跑一个线程

这个代码中有一个问题:在outText函数中,它始终将数据写入第0行第1列。你需要将它改为以正确的行和列写入数据。

另外,如果你想对每一行的数据分别进行倒计时,那么你需要将每一个倒计时的线程的sinOut信号与该行的单元格关联。

最后,请注意,当你删除qthraed实例时,请确保结束线程。

将每个时间值分配给单独的QThread,即每行单独跑一个线程,而且都在倒计时,这是风险很高的处理方案,很容易出问题。

这段代码的问题在于,代码中的 QThread 是无限循环的,且每次触发信号时都会对表格的第0行第1列赋值,导致表格界面不停刷新。

解决方法:

在线程运行完后调用exit()退出线程,以免无限循环。
在 outText 函数中,确定该修改的是哪一行的哪一列,而不是一直修改第0行第1列

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^