PyQt5的UI控件回调使用Qthread,UI不卡,新手总结,未完

先贴主函数入口文件代码:

代码思路点击pushbutton1、2、3则其绑定的回调函数pushbutton1、2、3 callback分别执行。

结论:由于pushbutton1每次回调都创建MyQthread实例,会卡UI,并且都会调用析构函数在终端输出“析构Mythread 实例”,有一点不解的终端竟然先出析构信息,后执行子线程(输出10987654321),求高手解答

pushbutton2、3(它俩一样的)都不会卡UI,并且每次点击按钮终端不会输出“析构Mythread 实例”

在线程MyQthread创建的时候加了参数main_ui用于传入主UI(可能不规范,可能会导致安全性不行),用来在线程执行中读取界面参数,至于能否直接修改界面显示元件内容还没实验,参考了许多博客都没有提及也没有提及如何在子线程内读取UI界面参数的博客,本文系原创,测试ok。关于Qthread::wait()可以参看https://bbs.csdn.net/topics/394475904

import sys,time
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QThread,pyqtSignal
from ui_find_usdt import Ui_UI_Usdt #导入PyQt5 UI界面自动生成的class

def get_exchange_usdt_addr(filename):
    print(filename)
    return {"filename":filename}

def handle_usdt(main_ui):
    try:
        data_path = main_ui.lineEdit.text()
        time0 = main_ui.dateTimeEdit.text()
        time1 = main_ui.dateTimeEdit_2.text()
        filename = main_ui.lineEdit_3.text()
        usdt_dic = get_exchange_usdt_addr(filename)#
        #故意设置的时延,用来检验UI界面是否会出现未响应
        sleeptime = 10
        while(sleeptime>0):
            print(sleeptime)
            sleeptime = sleeptime-1
            time.sleep(1)

        return "{}\r\n{}\r\n{}\r\n{}\r\n{}".format(data_path,filename,time0,time1,str(usdt_dic))
    except Exception as err:
        print(err)

class MyQthread(QThread):
    signal = pyqtSignal(str)    # 括号里填写信号传递的参数
    def __init__(self,main_ui):#run函数内访问UI读取参数,创建实例的时候记得传入UI实例
        super().__init__()
        self.main_ui=main_ui

    def __del__(self):
        print("析构Mythread 实例")
        self.wait()#不懂参看https://bbs.csdn.net/topics/394475904

    def run(self):
        msg = handle_usdt(self.main_ui)
        self.signal.emit(msg)    # 发射信号

class fun_main(Ui_UI_Usdt):
    def __init__(self,window_obj):
        Ui_UI_Usdt.__init__(self)
        Ui_UI_Usdt.setupUi(self,window_obj)
        self.mythread3 = MyQthread(self)#在UI对象创建时添加MyQthread实例
        self.mythread3.signal.connect(self.pushButton_3_callafter)
        #self.mythread3运行结束发送的信号绑定到UI对象内的函数上用于更新显示
        self.mythread2 = MyQthread(self)
        self.mythread2.signal.connect(self.pushButton_2_callafter)

        self.pushButton.clicked.connect(self.pushButton_callback)#UI按钮绑定回调函数
        self.pushButton_2.clicked.connect(self.pushButton_2_callback)
        self.pushButton_3.clicked.connect(self.pushButton_3_callback)

    def pushButton_callback(self):#按钮1的回调函数与2、3不同,每次回调都创建MyQthread,会卡UI
        print(self.pushButton.text())
        self.textBrowser.setText("")
        thread_callback = MyQthread(self)
        thread_callback.signal.connect(self.pushButton_callafter)
        thread_callback.start()

    def pushButton_callafter(self,msg):
        self.textBrowser.setText(msg)

    def pushButton_2_callback(self):
        print(self.pushButton_2.text())
        self.textBrowser.setText("")
        self.mythread2.start()

    def pushButton_2_callafter(self,msg):
        self.textBrowser.setText(msg)

    def pushButton_3_callback(self):
        print(self.pushButton_3.text())
        self.textBrowser.setText("")
        self.mythread3.start()

    def pushButton_3_callafter(self,msg):
        print(msg)
        self.textBrowser.setText("123")


if __name__=='__main__':
    app = QApplication(sys.argv)
    Mwindow = QMainWindow()
    ui = fun_main(Mwindow)
    Mwindow.show()
    sys.exit(app.exec())

 

二、关于自己新建的线程类里面可以不写自定义信号而使用标准信号,线程可以多信号,参考https://blog.csdn.net/weixin_41622043/article/details/87880106比如在UI类内部设定收到这些信号,未测试

#相应的mythread类内要发送该信号则可以这样写:


class mythread(QThread):
    '''线程类'''
    def __init__(self,main_ui):
        QThread.__init__(self)
 
    def __del__(self):
        self.wait()
 
    def myfunc(self, main_ui):
        return main_ui.pushButton.text()
 
    def run(self):
        msg = myfunc(self, main_ui)
        self.emit(SIGNAL("自定义字符串"), msg)


class ThreadingTutorial(QtGui.QMainWindow, design.Ui_MainWindow):

    """主逻辑类,需要继承UI类"""
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.test)
        self.mythread = mythread(self)
        self.mythread.connect(SIGNAL("finished()"), self.done)#绑定结束信号,不传参数
        self.mythread.connect(SIGNAL("自定义字符串"), self.display)#绑定自定义信号,有参msg

    def test(self):
        self.mythread.start()

    def done(self):#接收结束信号,不传参数
        print("thread finished")

    def display(self,msg): #接收结束信号,传参msg
        print(msg)  

以上理解可能出错的是   

self.emit(SIGNAL("自定义字符串"), msg)
self.mythread.connect(SIGNAL("自定义字符串"), self.display)#绑定自定义信号,有参msg

可以参考https://nikolak.com/pyqt-threading-tutorial/,应该需要填写函数和函数接收参数类型的样子

关于信号可以参考https://www.riverbankcomputing.com/static/Docs/PyQt5/#

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值