欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

pyqt5 tablewidget 利用线程动态刷新数据的方法

程序员文章站 2023-12-12 16:18:35
问题 知道要用线程,所以就先尝试写了一个线程,然后每次都获取数据,然后直接通过这种方法来朝table里面更新数据。 #python代码 table=mainw...

问题

知道要用线程,所以就先尝试写了一个线程,然后每次都获取数据,然后直接通过这种方法来朝table里面更新数据。

#python代码
table=mainwindow_ui.tablewidget_2
table.setitem(i,0,qtwidgets.qtablewidgetitem(str(jcb.name)))

发现数据并不是想象中跟线程运行那样实时的,要点一下才能显示出数据来

并且还会出现一些问题

问题图片

为了做出对比,我将作业名的表格填写改成table.setitem的方式,其他格子用信号量机制,可以很清楚的看到问题所在!!!!

pyqt5 tablewidget 利用线程动态刷新数据的方法

解决方法

核心是要通过qt的槽函数来发射信号告知qt窗口的组件来进行更新,如果是直接程序上来“发射接受”信号,而不通过qt的槽函数来弄就会出现问题

thread函数

原本class里面自己写的是一个python的threading包的线程,利用threading.event()来进行进程阻塞,没想到直接修改成 qtcore.qthread,两个混合在一起也能用。。。

class job(qtcore.qthread):#注意这里使用的是qt自己本身的线程,而不能用python自己的线程
  signal2=qtcore.pyqtsignal(tuple)#因为这个信号槽要继承于qobject,不然会发生没有emit,connect函数的报错,括号里面填写的是发射的数据类型
  def signal2emit(self,var:tuple):
    self.signal2.emit(var)#朝connect的函数发射一个tuple

  def __init__(self, *args, **kwargs):#这里自己实现
    super(job, self).__init__(*args, **kwargs)
    self.__flag = threading.event()   # 用于暂停线程的标识
    self.__flag.set()    # 设置为true
    self.__running = threading.event()   # 用于停止线程的标识
    self.__running.set()   # 将running设置为true
    self.signal2.connect(setitem)#连接发射函数

  def run(self):
    global systemtime,timepice#声明要用的全局变量
    while self.__running.isset():#如果被设置为了true就继续,false就终止了
      self.__flag.wait()   # 为true时立即返回, 为false时阻塞直到内部的标识位为true后返回
      ###################
      #这里写线程要干的事情#
      ###################
      time.sleep(1)

  def pause(self):
    self.__flag.clear()   # 设置为false, 让线程阻塞

  def resume(self):
    self.__flag.set()  # 设置为true, 让线程停止阻塞

  def stop(self):
    self.__flag.set()    # 将线程从暂停状态恢复, 如何已经暂停的话
    self.__running.clear()    # 设置为false 

setitem函数,接受信号量

def setitem(var:tuple):#用于向jcb表格填写内容
  i=var[0]#行
  j=var[1]#列
  s=var[2]#值
  table=mainwindow_ui.tablewidget_2
  if j != 6 :
    table.setitem(i,j,qtwidgets.qtablewidgetitem(str(s)))
  else :
    table.cellwidget(i,6).setvalue(s)#这是个进度条来的

朝表格中填写数据的函数

这是放在主线程中该干的事情的一部分

其中注释掉的部分就是之前直接朝表格中set数据的部分,这是不行的,要通过qthread来发射信号量

def print_job():
  rowcol=len(jcb_ready_list)+len(jcb_wait_list)
  print(rowcol)
  #mainwindow_ui.tablewidget_2.setrowcount(rowcol)
  for i in range(0,rowcol):
    mainwindow_ui.tablewidget_2.showrow(i)
  #for i in range(rowcol,100):
  #  mainwindow_ui.tablewidget_2.hiderow(i)
  for i in range(0,len(jcb_ready_list)):
    jcb=jcb_ready_list[i]
    table=mainwindow_ui.tablewidget_2
                     #table.setitem(i,0,qtwidgets.qtablewidgetitem(str(jcb.name)))
    mainthread.signal2emit((i,0,jcb.name))
    #table.setitem(i,1,qtwidgets.qtablewidgetitem(str(jcb.arrival_time)))
    mainthread.signal2emit((i,1,jcb.arrival_time))
    #table.setitem(i,2,qtwidgets.qtablewidgetitem(str(jcb.need_memory)))
    mainthread.signal2emit((i,2,jcb.need_memory))
    #table.setitem(i,3,qtwidgets.qtablewidgetitem(str(jcb.need_time)))
    mainthread.signal2emit((i,3,jcb.need_time))
    #table.setitem(i,4,qtwidgets.qtablewidgetitem(str(jcb.already_execution_time)))
    mainthread.signal2emit((i,4,jcb.already_execution_time))
    #table.setitem(i,5,qtwidgets.qtablewidgetitem(str(jcb.wait_time)))
    mainthread.signal2emit((i,5,jcb.wait_time))
    #bar:qtwidgets.qprogressbar=mainwindow_ui.tablewidget_2.cellwidget(i,6)
    #bar.setvalue(100-jcb.need_time/(jcb.already_execution_time+jcb.need_time)*100)
    mainthread.signal2emit((i,6,100-jcb.need_time/(jcb.already_execution_time+jcb.need_time)*100))

成果

这样就顺利实现了table widget的动态更新数据

pyqt5 tablewidget 利用线程动态刷新数据的方法

以上这篇pyqt5 tablewidget 利用线程动态刷新数据的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

上一篇:

下一篇: