欢迎光临散文网 会员登陆 & 注册

QThread多线程

2022-11-11 10:36 作者:海鸥之道  | 我要投稿

        QThread是Qt线程类中最核心的底层类。由于PyQt 的跨平台特性,QThread要隐藏所有与平台相关的代码。要使用QThread开始一个线程,可以创建它的一个子类,然后覆盖其QThread.run()函数。

接下来创建一个新的线程。

        可以看出,PyQt的线程的使用非常简单一建立一个自定 义的类(如Thread),

使它继承自QThread,并实现其run(方法即可。

        在使用线程时可以直接得到Thread实例,调用其start()函数即可启动线程。线

程启动之后,会自动调用其实现的run方法,该方法就是线程的执行函数。

        业务的线程任务就写在run()函数中,当run()退 出之后线程基本就结束了。QThread有started 和finished 信号,可以为这两个信号指定槽函数,在线程启动和结束时执行一段代码进行资源的初始化和释放操作。更灵活的使用方法是,在自定义的QThread实例中自定义信号,并将信号连接到指定的槽函数,当满足一定的业务条件后发射此信号。

1、QThread类中的常用方法和信号

QThread类中的常用方法如下表所示。

QThread类中的常用信号如下表所示:

2、QThread实例

当在窗口中显示的数据比较简单时,可以把读取数据的业务逻辑放在窗口的初始化代码中;但如果读取数据的时间较长,比如网络请求数据的时间比较长,则可以把这部分逻辑放在QHread线程中,实现界面的数据显示和数据读取的分离,满足MVC(模型--视图--控制器)设计模式的要求。

实例演示1:

运行程序,点击开始,显示效果如下:

代码分析:

        在这个例子中,单击开始按钮,会在后台定时读取数据,并把返回的数据显示在界面中,首先使用以下代码进行布局,把列表控件和按钮控件放在栅格布局管理器中:

        然后将按钮的clicked信号连接到slotStart()槽函数,当单击“开始”按钮时发射此信号:

        比较负载的是线程的信号,将线程的sinOut信号连接到slotAdd()槽函数。slotAdd()函数负责在列表控件中动态添加字符串条目。

        定义一个线程类,继承自QThread类,当线程启动后,执行run()函数。

        在上一个例子中,虽然解决了界面的数据显示和数据读取的分离,但是如果数据读取非常耗费时间,则会造成界面卡死。接下来,我们看下一个耗费很长时间读取数据的例子:

实例演示2:

运行程序,显示效果如下图:

        在这个例子中,在主界面中有一个用于显示时间的LCD数字面板,还有一个用于启动任务的按钮。用户单击“测试”按钮后,将开始- -次非常耗时的计算(在程序中用一个2 000 000 000次的循环来模拟这次非常耗时的工作,在真实的程序中可能是一个网络下载操作,从网络上下载一个很大的视频文件),同时LCD数字面板开始显示所用的毫秒数,并通过一一个计时器进行更新。计算完成后,计时器停止。这是一个很简单的应用,也看不出有任何问题。但是当开始运行程序时,问题就来了:单击“测试”按钮之后,程序界面直接停止响应,直到循环结束才开始重新更新,于是计时器始终显示0。

    在PyQt中所有的窗口都在UI主线程中(就是执行了QApplication.exec(的线程),在这个线程中执行耗时的操作会阻塞UI 线程,从而让窗口停止响应。如果窗口长时间没有响应,则会影响用户体验,更严重的会导致程序崩溃。所以,为了避免出现这样的问题,要使用QThread开启一个新的线程,在这个线程中完成耗时的操作。

实例演示3:分离主线程与工作线程

运行结果如下:
















QThread多线程的评论 (共 条)

分享到微博请遵守国家法律