最近开发一个项目,需要用到界面,遇到界面不能实时更新的问题,看到网上很多用槽函数,但是大多都是些button的,并不是我需要的,要么就是整数的,后来自己进行尝试,写了一个自定义的槽函数处理treewidget,特地分享出来。

背景:用QT Designer设计了一个界面,在程序运行中间调用界面,并随着程序的运行会更新treewidget。

问题1:如果在界面Class中写运行程序,那么结果会等到程序运行结束,最后界面出来,但是此时界面上已经是最终结果

解答:因为会等到程序结束才会加入界面mainloop中,执行到最后一句话,界面才会显示,所以解决办法就是将中间需要处理的代码放到线程中,这样就不会妨碍程序往下走了。

问题二:在线程中代码会需要更新界面,但是界面往往卡顿,只有鼠标点cmd窗口,在点回界面时,数据才刷新,不能更好的看到程序运行的结果。

解答:PyQt5中不友好支持子线程中对界面的设置,需要使用槽函数,信号触发的方式来更新界面。

为了更好的演示,这里先介绍一下把界面和代码分离的方法

现在开始自定义槽函数。

先看分离后的函数:

treeview4_test.py

from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
from PyQt5 import QtCore, QtGui, QtWidgets
import treeview4
import treeview_data
import sys class MainCode(QMainWindow, treeview4.Ui_MainWindow): def __init__(self):
QMainWindow.__init__(self)
treeview4.Ui_MainWindow.__init__(self)
self.setupUi(self)
# 设置列宽
self.treeWidget.setColumnWidth(0, 200) _translate = QtCore.QCoreApplication.translate
self.initial_tree_view(_translate)
self.treeWidget.expandAll() def initial_tree_view(self, _translate):
list_objects = []
test1 = treeview_data.DataCollection()
test1.set_module({"Test1": "waiting"})
test1.add_item({"a1": "waiting"})
test1.add_item({"b1": "waiting"})
test1.add_item({"c1": "waiting"})
list_objects.append(test1) test2 = treeview_data.DataCollection()
test2.set_module({"Test2": "waiting"})
test2.add_item({"a2": "waiting"})
test2.add_item({"b2": "waiting"})
test2.add_item({"c2": "waiting"})
test2.add_item({"d2": "waiting"})
list_objects.append(test2) test3 = treeview_data.DataCollection()
test3.set_module({"Test3": "waiting"})
test3.add_item({"a2": "waiting"})
test3.add_item({"b2": "waiting"})
test3.add_item({"c2": "waiting"})
test3.add_item({"d2": "waiting"})
list_objects.append(test3) for object_num, object_module in enumerate(list_objects):
item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
brush = QtGui.QBrush(QtGui.QColor(176, 165, 172))
brush.setStyle(QtCore.Qt.SolidPattern)
item_0.setBackground(0, brush)
for module_name, module_result in object_module.module.items():
brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
item_0.setBackground(1, brush)
self.treeWidget.topLevelItem(object_num).setText(0, _translate("MainWindow", module_name))
self.treeWidget.topLevelItem(object_num).setText(1, _translate("MainWindow", module_result))
for item_num, item_dic in enumerate(object_module.items):
for item_name, item_result in item_dic.items():
item_1 = QtWidgets.QTreeWidgetItem(item_0)
self.treeWidget.topLevelItem(object_num).child(item_num).setText(0, _translate("MainWindow",
item_name))
self.treeWidget.topLevelItem(object_num).child(item_num).setText(1, _translate("MainWindow",
item_result)) if __name__ == "__main__":
app = QApplication(sys.argv)
md = MainCode()
md.show()
app.exec_()
# sys.exit(app.exec_())

然后调用子线程进行刷新:

from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
from PyQt5 import QtCore, QtGui, QtWidgets
import treeview4
import treeview_data
import sys
import threading
import time class MainCode(QMainWindow, treeview4.Ui_MainWindow):
list_result_update = QtCore.pyqtSignal([int, int, str]) def __init__(self):
QMainWindow.__init__(self)
treeview4.Ui_MainWindow.__init__(self)
self.setupUi(self)
# 设置列宽
self.treeWidget.setColumnWidth(0, 200) _translate = QtCore.QCoreApplication.translate
self.initial_tree_view(_translate)
self.treeWidget.expandAll()
# 用列表触发槽函数
self.list_result_update.connect(self.modified_treewidget)
# 线程函数
self.run() def run(self):
th = threading.Thread(target=self.go_update)
th.setDaemon(True)
th.start() def initial_tree_view(self, _translate):
list_objects = []
test1 = treeview_data.DataCollection()
test1.set_module({"Test1": "waiting"})
test1.add_item({"a1": "waiting"})
test1.add_item({"b1": "waiting"})
test1.add_item({"c1": "waiting"})
list_objects.append(test1) test2 = treeview_data.DataCollection()
test2.set_module({"Test2": "waiting"})
test2.add_item({"a2": "waiting"})
test2.add_item({"b2": "waiting"})
test2.add_item({"c2": "waiting"})
test2.add_item({"d2": "waiting"})
list_objects.append(test2) test3 = treeview_data.DataCollection()
test3.set_module({"Test3": "waiting"})
test3.add_item({"a2": "waiting"})
test3.add_item({"b2": "waiting"})
test3.add_item({"c2": "waiting"})
test3.add_item({"d2": "waiting"})
list_objects.append(test3) for object_num, object_module in enumerate(list_objects):
item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
brush = QtGui.QBrush(QtGui.QColor(176, 165, 172))
brush.setStyle(QtCore.Qt.SolidPattern)
item_0.setBackground(0, brush)
for module_name, module_result in object_module.module.items():
brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
item_0.setBackground(1, brush)
self.treeWidget.topLevelItem(object_num).setText(0, _translate("MainWindow", module_name))
self.treeWidget.topLevelItem(object_num).setText(1, _translate("MainWindow", module_result))
for item_num, item_dic in enumerate(object_module.items):
for item_name, item_result in item_dic.items():
item_1 = QtWidgets.QTreeWidgetItem(item_0)
self.treeWidget.topLevelItem(object_num).child(item_num).setText(0, _translate("MainWindow",
item_name))
self.treeWidget.topLevelItem(object_num).child(item_num).setText(1, _translate("MainWindow",
item_result)) def modified_treewidget(self, num_one, num_two, str_one):
_translate = QtCore.QCoreApplication.translate
self.treeWidget.topLevelItem(num_one).child(num_two).setText(1, _translate(
"MainWindow",
str_one)) def go_update(self):
time.sleep(1)
# 更新treeview
self.list_result_update.emit(1, 1, "aaaaaaa") if __name__ == "__main__":
app = QApplication(sys.argv)
md = MainCode()
md.show()
app.exec_()
# sys.exit(app.exec_())

现在就完成了自定义槽函数了。

Python基础之用PyQt5界面代码分离以及自定义一个槽函数的更多相关文章

  1. 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码

    引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...

  2. python基础--小数据池,代码块的最详细、深入剖析

    本文转至太白金星 一,id,is,== 在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存 ...

  3. Python基础库之jieba库的使用(第三方中文词汇函数库)

    各位学python的朋友,是否也曾遇到过这样的问题,举个例子如下: “I am proud of my motherland” 如果我们需要提取中间的单词要走如何做? 自然是调用string中的spl ...

  4. python基础-requests模块、异常处理、Django部署、内置函数、网络编程

     网络编程 urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应. 校验返回值,进行接口测试: 编码:把一个Python对象编码转 ...

  5. Python基础总结之第十一天开始【再深入一下函数,重新认识一下】(新手可相互督促)

    感谢最近大家的关注,希望我的学习笔记对大家有帮助!也感谢各位的评论和推荐,请多多指教. 在重新认识函数之前,我们先看两个函数.一个是我们在前面笔记经常用到的print()  :另一个是input() ...

  6. PyQt(Python+Qt)学习随笔:Qt Designer中连接Action和槽函数

    在Designer中试了半天,终于找到了Action添加槽函数的方法,操作步骤: 在Designer右边界面中点击鼠标右键 确保信号/槽编辑被勾选,如图是未勾选的情况:. 勾选后会出现信号和槽的编辑界 ...

  7. python基础===如何优雅的写代码(转自网络)

    本文是Raymond Hettinger在2013年美国PyCon演讲的笔记(视频, 幻灯片). 示例代码和引用的语录都来自Raymond的演讲.这是我按我的理解整理出来的,希望你们理解起来跟我一样顺 ...

  8. python基础知识-8-三元和一行代码(推导式)

    python其他知识目录 1.三元运算(三目运算) 三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值格式:[on_true] if [expression] else [on_false]re ...

  9. Python基础之用PyQt5写一个tabview

    前面学习了menu的画图,现在学习tabview的画图,关于怎么打开designer.exe部分就不详细介绍了. 第一步:拖动一个Tab Widget控件到窗口去. 将控件拖上去之后就是这个样子,默认 ...

随机推荐

  1. Spring @Transaction 注解是如何执行事务的?

    前言 相信小伙伴一定用过 @Transaction 注解,那 @Transaction 背后的秘密又知道多少呢? Spring 是如何开启事务的?又是如何进行提交事务和关闭事务的呢? 画图猜测 在开始 ...

  2. Bootstrap中宽度大于指定宽度时有空白的解决方法

    <div class="container-fluid"></div> 其中container-fluid的作用是占100%

  3. 服务器硬件和RAID配置

    服务器 硬件和RAID配置 目录 一.RAID 磁盘阵列介绍 1.1.RAID 0(条带化存储) 1.2.RAID 1(镜像存储) 1.3.RAID 5 1.4.RAID 6 1.5.RAID 1+0 ...

  4. ES6的 class的基本语法

    1.类的由来 JavaScript 语言中,生成实例对象的传统方法是通过构造函数,但是这种写法跟传统的面向对象语言差异很大,容易让不熟悉这门语言的程序员感到困惑,下面有一个例子    ES6提供了更接 ...

  5. Kubernetes之DaemonSet

    1.DaemonSet在每个节点上运行一个pod K8s中Replicationcontroller和ReplicaSet都用于在Kubernetes集群上运行部署特定数量的pod.但是,当希望pod ...

  6. hive学习笔记之七:内置函数

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. Nginx网站服务

    1.常见的网站服务 静态网站服务: Apache服务 nginx服务 动态网站服务: Tomcat服务 PHP 2.nginx网站服务特点 (1)nginx具有高并发(特别是静态资源).占用系统资源少 ...

  8. 微信小程序 添加左边固定浮动框

    view: <!-- 悬浮框 --> <view class="v-fixed-title1"> <view class="v-fixed- ...

  9. js jquey 笔记

    1.使用insertAfter 如果插入在tr后添加多行数据,数据会倒过来注意组字符串需要倒着循环 1).html方法,给元素添加html代码或者清空html代码(参数为空字符串): 2).appen ...

  10. JavaScript中for...in循环使用问题

    问题 使用for...in去遍历一个数组,同时将值添加到另外一个数组时,新的数组中每次都多出来一个function类型的元素. 原因及解决方案 for...in用来循环本身没有问题,但是经常被误用来遍 ...