(三)多线程编程
如果一次只完成一件事情,那是一个不错的想法,但事实上很多事情都是同时进行的,所以在Python中为了模拟这种状态,引入了线程机制,简单地说,当程序同时完成多件事情时,就是所谓的多线程程序。多线程应用广泛,开发人员可以使用多线程程序对要执行的操作分段执行,这样可以大大提高程序的运行速度和性能。
我们先对线程的分类及概述做简单介绍,然后详细讲解Python中进行线程编程的主要两个类——QTimer计时器类、QThread线程类,并对线程的具体实现进行详细讲解。之后,我们就可以熟悉使用Python进行线程编程的基础知识,并在实际开发中应用线程处理多任务问题。
1. 线程概述
世间万物都会同时完成很多工作,例如,人体同时进行呼吸、血液循环、思考问题等活动,用户既可以使用计算机听歌,又可以使用它打印文件,而这些活动完全可以同时进行,这种思想放在Python中被称为并发,而将并发完成的每一件事情称为线程。
1. 线程的定义与分类
先了解一个概念——进程。系统中资源分配和资源调度的基本单位,叫做进程。其实进程很常见,我们使用的QQ、Word、甚至是输入法等,每个独立执行的程序在系统中都是一个进程。
每个进程中都可以同时包含多个线程,例如,QQ是一个聊天软件,但它的功能有很多,如收发信息、播放音乐、查看网页和下载文件等,这些工作可以同时运行并且互不干扰,这就是使用了线程的并发机制,我们把QQ这个软件看作一个进程,而它的每一个功能都是一个可以独立运行的线程。

上面介绍了一个进程可以包括多个线程,但计算机的CPU只有一个,那么这些线程是怎么做到并发运行的呢?Windows操作系统是多任务操作系统,它以进程为单位,每个独立执行的程序称为进程,在系统中可以分配给每个进程一段有限的使用CPU的时间(也可以称为CPU时间片),CPU在片段时间中执行某个进程,然后下一个时间片又跳至另一个进程中去执行。由于CPU转换较快,所以使得每个进程好像是同时执行一样。

一个线程则是进程中的执行流程,一个进程中可以同时包括多个线程,每个线程也可以得到一小段程序的执行时间,这样一个进程就可以具有多个并发执行的线程。
2. 多线程的优缺点
一般情况下,需要用户交互的软件都必须尽可能快地对用户的操作做出反应,以便提供良好的用户体验,但同时它又必须执行必要的计算以便尽可能快地将数据呈现给用户,这时可以使用多线程来实现。
1. 多线程的优点
要提高对用户的相应速度,使用多线程是一种最有效的方式,在具有一个处理器的计算机上,多线程可以通过利用用户事件之间很小的时间段在后台处理数据来达到这种效果。多线程的优点如下:
- 通过网络与Web服务器和数据库进行通信。
- 执行占用大量时间的操作。
- 区分具有不同优先级的任务。
- 使用户界面可以在将时间分配给后台任务时仍能快速做出响应。
2. 多线程的缺点
多线程有好处,同时也有坏处,建议一般不要在程序中使用太多的线程,这样可以最大限度地减少操作系统资源的使用,并提高性能。使用多线程可能对程序造成的负面影响如下:
- 系统将为进程和线程所需的上下文信息使用内存。因此,可以创建的进程和线程的数目会受到可用内存的限制。
- 跟踪大量的线程将占用大量的处理器时间。如果线程过多,则其中大多数线程都不会产生明显的进度。如果大多数线程处于一个进程中,则其他进程中的线程的调度频率就会很低。
- 使用多个线程控制代码执行非常复杂,并可能产生许多Bug。
- 销毁线程需要了解可能发生的问题并进行处理。
在PyQt5中实现多线程主要有两种方法,一种是使用QTimer计时器模块;另一种是使用QThread线程模块。
2. QTimer:计时器
在PyQt5程序中,如果需要周期性地执行某项操作,就可以使用QTimer类实现,QTimer类表示计时器,它可以定期发射timeout信号,时间间隔的长度在start()方法中指定,以毫秒为单位,如果要停止计时器,则需要使用stop()方法。
在使用QTimer类时,首先需要进行导入:
from PyQt5.QtCore import QTimer
示例:双色球彩票选号器
使用PyQt5实现模拟双色球选号的功能。
(1)在PyQt5的Qt Designer设计器中创建一个窗口,设置背景,并添加7个Label标签和两个PushButton按钮。
(2)将设计的窗口保存为.ui文件,并使用PyUIC工具将其转换为.py文件,同时使用qrcTOpy工具将用到的存储图片的资源文件转换为.py文件。这部分的代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(435, 294)
MainWindow.setWindowTitle("双色球彩票选号器") # 设置窗口标题
# 设置窗口背景图片
MainWindow.setStyleSheet("border-image: url(./image/双色球彩票选号器.png)")
self.centralwidget=QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# 创建第一个红球数字的标签
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(97, 178,31, 31))
# 设置标签的字体
font = QtGui.QFont() # 创建字体对象
font.setPointSize(16) # 设置字体大小
font.setBold(True) # 设置粗体
font.setWeight(75) # 设置字体
self.label.setFont(font) # 为标签设置字体
# 设置标签的文字颜色
self.label.setStyleSheet("color:rgb(255,255,255);")
self.label.setObjectName("label")
# 第2、3、4、5、6个红球和一个蓝球标签的代码的创建及设置代码与第一个红球标签的代码一样
# 创建第2个红球
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(128, 178, 31, 31))
self.label_2.setFont(font) # 为标签设置字体
self.label_2.setStyleSheet("color:rgb(255,255,255);") # 设置标签的文字颜色
self.label_2.setObjectName("label_2")
# 创建第3个红球
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(159, 178, 31, 31))
self.label_3.setFont(font) # 为标签设置字体
self.label_3.setStyleSheet("color:rgb(255,255,255);") # 设置标签的文字颜色
self.label_3.setObjectName("label_3")
# 创建第4个红球
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(190, 178, 31, 31))
self.label_4.setFont(font) # 为标签设置字体
self.label_4.setStyleSheet("color:rgb(255,255,255);") # 设置标签的文字颜色
self.label_4.setObjectName("label_4")
# 创建第个5红球
self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setGeometry(QtCore.QRect(221, 178, 31, 31))
self.label_5.setFont(font) # 为标签设置字体
self.label_5.setStyleSheet("color:rgb(255,255,255);") # 设置标签的文字颜色
self.label_5.setObjectName("label_5")
# 创建第6个红球
self.label_6 = QtWidgets.QLabel(self.centralwidget)
self.label_6.setGeometry(QtCore.QRect(252, 178, 31, 31))
self.label_6.setFont(font) # 为标签设置字体
self.label_6.setStyleSheet("color:rgb(255,255,255);") # 设置标签的文字颜色
self.label_6.setObjectName("label_6")
# 创建第7个红球
self.label_7 = QtWidgets.QLabel(self.centralwidget)
self.label_7.setGeometry(QtCore.QRect(283, 178, 31, 31))
self.label_7.setFont(font) # 为标签设置字体
self.label_7.setStyleSheet("color:rgb(255,255,255);") # 设置标签的文字颜色
self.label_7.setObjectName("label_7")
# 创建“开始”按钮
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(310, 235, 51, 51))
# 设置按钮的背景图片
self.pushButton.setStyleSheet("border-image: url(./im

最低0.47元/天 解锁文章





