Python基礎之用PyQt5界面代碼分離以及自定義一個槽函數


最近開發一個項目,需要用到界面,遇到界面不能實時更新的問題,看到網上很多用槽函數,但是大多都是些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_())
View Code

 

然后調用子線程進行刷新:

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

 

現在就完成了自定義槽函數了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM