在一个应用中,除了一个主线程外,往往还有其他一些线程同时在进行工作,比如可能一个线程负责采集数据,另外一些线程负责数据分析,转发,保存或者显示等等,这时候就可以在数据采集线程中将数据通过信号的形式发送到后续处理线程,后续线程实现相应的槽函数来处理数据分析、转发,保存和显示等等。
无论是在Qt中还是Windows系统中UI刷新,都要求在主线程里完成,否则就可能出现系统出错的问题。在Qt中,如果在别的线程中想对UI进行刷新,则可以通过信号与槽的方式来实现。比如我们有一个线程进行图像采集,使用一个部件进行图像显示,这种情况下就可以使用信号还传递采集数据,在主线程中完成显示。
测试代码在程序中,从QThread派生出一个子类MyThread, 作为一个计数器,每100毫秒,计数器加1,然后通过自定义信号将该计数发射出去,在主线程中,QLCDNumber液晶显示面板收到该计数后,将计数显示出来。点击开始按钮,计数器开始运行,点击结束,计数器停止运行,并恢复为0, 在程序退出前,使用CloseEvent来处理对线程的中断操作。完整代码如下:
import sysfrom PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import QThread, pyqtSignalfrom PyQt5.QtGui import QCloseEventfrom PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, QLCDNumber) class MyThread(QThread): countChanged = pyqtSignal(int) def __init__(self, parent=None): super(MyThread, self).__init__(parent) self.count = 0 def resetCount(self): self.count = 0 def run(self): while True: self.msleep(100) self.count += 1 self.countChanged.emit(self.count) class DemoThreadSignalSlot(QWidget): def __init__(self, parent=None): super(DemoThreadSignalSlot, self).__init__(parent) # 设置窗口标题 self.setWindowTitle('实战PyQt5: 线程间使用信号与槽') # 设置窗口大小 self.resize(360, 200) self.initUi() def initUi(self): mainLayout = QVBoxLayout() # 液晶数字显示 self.lcd = QLCDNumber() mainLayout.addWidget(self.lcd) self.btnStart = QPushButton('开始') self.btnStart.setMinimumHeight(60) self.btnStart.clicked.connect(self.onBtnStart) mainLayout.addWidget(self.btnStart) self.setLayout(mainLayout) self.thread = MyThread(self) self.thread.countChanged.connect(self.lcd.display) self.start = False def onBtnStart(self): if not self.thread is None: if self.start == False: self.start = True self.btnStart.setText('结束') self.thread.start() else: self.start = False self.btnStart.setText('开始') if self.thread.isRunning: self.thread.terminate() self.thread.quit() self.thread.resetCount() self.lcd.display(0) # 关闭时调用 def closeEvent(self, event): if not self.thread is None: if(self.thread.isRunning): self.thread.terminate() self.thread.quit() if __name__ == '__main__': app = QApplication(sys.argv) window = DemoThreadSignalSlot() window.show() sys.exit(app.exec())运行结果如下图:
本文知识点QThread的基本用法;在线程中使用自定义信号;线程间的数据传递;了解QCloseEvent。喜欢本文内容就关注, 收藏,点赞,评论和转发。
探究问题
水分蒸发的速度
三、假设
① 水分蒸发的速度可能与温度有关
② 水分蒸发的速度可能与液体表面积有关
③ 水分蒸发的速度可能与液体表面空气流动速度有关
四、实验方案
每组实验均使用20ml的水,均用时5分钟。两杯同时进行实验。
实验①(对应假设①)
条件
甲杯
乙杯
水温
沸水(80℃左右)
冷水(20℃左右)
液体表面积
碗碟开口
碗碟开口
液体表面空气流动速度
同样放置在清凉条件下
同样放置在清凉条件下
为加快实验速度,都对两杯水做加快液体表面空气流动速度、使用大开口的处理。
实验②(对应假设②)
条件
甲杯
乙杯
水温
沸水(80℃左右)
沸水(80℃左右)
液体表面积
碗碟开口(开口大于玻璃杯)
玻璃杯开口
液体表面空气流动速度
同样放置在清凉条件下
同样放置在清凉条件下
为加快实验速度,都对两杯水做加快液体表面空气流动速度、使用沸水的处理。
实验③(对应假设③)
条件
甲杯
乙杯
水温
沸水(80℃左右)
沸水(80℃左右)
液体表面积
碗碟开口
碗碟开口
液体表面空气流动速度
放置在清凉条件下
放置在不通风条件下
为加快实验速度,都对两杯水做使用沸水、使用大开口的处理。
五、收集的数据
实验①(对应假设①)
收集数据
甲杯
乙杯
蒸发前水的质量/蒸发后水的质量
20ml/17ml
20ml/20ml
蒸发前水的温度/蒸发后水的温度
80℃/31℃
20℃/19℃
实验②(对应假设②)
收集数据
甲杯
乙杯
蒸发前水的质量/蒸发后水的质量
20ml/17ml
20ml/19ml
蒸发前水的温度/蒸发后水的温度
80℃/31℃
20℃/20℃
实验③(对应假设③)
收集数据
甲杯
乙杯
蒸发前水的质量/蒸发后水的质量
20ml/17ml
20ml/20ml
蒸发前水的温度/蒸发后水的温度
80℃/31℃
20℃/19℃
六、结论
水温越高蒸发速度越快,水温越低蒸发速度越慢。
水的表面积越大蒸发速度越快,水的表面积越小蒸发速度越慢。
水的表面空气流动速度越快蒸发速度越快,水的表面空气流动速度越慢蒸发速度越慢。
由于实验仪器不是很标准,所以数据存在误差。
资料到网上去搜啊,用百度搜索,输入“水分蒸发”等等。主要项目:温度,蒸发面积,水分含量及状态等。还有流量方面知识。数据自己研究啊,想15分就得到你说的答案,呵呵 ,太天真了吧!这属于课题研究,知道不?
JAVA多来自线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。http://blog.***.net/aboy123/article/details/38307539
详细可以参考这个,有图解教程,希望可以帮到你