脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - pyqt5 tablewidget 利用线程动态刷新数据的方法

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

2021-07-13 00:38请叫我西木同学 Python

今天小编就为大家分享一篇pyqt5 tablewidget 利用线程动态刷新数据的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

问题

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

?
1
2
3
#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,两个混合在一起也能用。。。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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函数,接受信号量

?
1
2
3
4
5
6
7
8
9
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来发射信号量

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 利用线程动态刷新数据的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq965194745/article/details/78943282

延伸 · 阅读

精彩推荐