信号

  信号是用于界面自动变化的一个工具,原理是信号绑定了一个函数,当信号被触发时函数即被调用

举个例子

from PyQt5 import QtWidgets,QtCore
from untitled import Ui_Form
import time class MyWindow(QtWidgets.QWidget,Ui_Form):
_signal=QtCore.pyqtSignal(str) #定义信号,定义参数为str类型
def __init__(self):
super(MyWindow,self).__init__()
self.setupUi(self)
self.myButton.clicked.connect(self.myPrint)# 按下按钮执行myPrint
self._signal.connect(self.mySignal) #将信号连接到函数mySignal def myPrint(self):
self.tb.setText("")
self.tb.append("正在打印,请稍候")
self._signal.emit("打印结束了吗")# 信号被触发
def mySignal(self,string):
print(string)
self.tb.append("打印结束") if __name__=="__main__":
# 以下代码作用为展现ui界面
import sys app=QtWidgets.QApplication(sys.argv)
myshow=MyWindow()
myshow.show()
sys.exit(app.exec_())

定时器

  定时器的作用是让某个函数定时的启动,原理是创建一个QTimer对象,将其timeout信号连接到相应的槽(绑定函数名),并调用start(),定时器会以恒定的间隔发出timeout信号,直到调用stop()。

举个例子:秒表功能(每隔一秒刷新界面,直到按下停止按钮)

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
from datetime import datetime class WinTimer(QWidget):
def __init__(self,parent=None):
super(WinTimer,self).__init__(parent) ###界面显示
self.label_start=QLabel("开始时间:")
self.label_curr=QLabel("当前时间:")
self.label_total=QLabel("时间总计:")
self.startBtn=QPushButton("开始")
self.endBtn=QPushButton("停止")
self.endBtn.setEnabled(False) ##时间变量
self.start_time=QDateTime.currentDateTime()
self.stop_time = QDateTime.currentDateTime() ###定时器
self.timer=QTimer()
self.timer.timeout.connect(self.currTime) layout=QGridLayout()
layout.addWidget(self.label_start,0,0,1,2)
layout.addWidget(self.label_curr, 1,0,1,2)
layout.addWidget(self.label_total, 2,0,1,2)
layout.addWidget(self.startBtn, 3, 0)
layout.addWidget(self.endBtn, 3, 1)
self.setLayout(layout) self.startBtn.clicked.connect(self.startTimer)
self.endBtn.clicked.connect(self.endTimer) self.setWindowTitle("QTimer")
self.resize(250,100) def currTime(self):
self.stop_time=QDateTime.currentDateTime()
str_time = self.stop_time.toString("yyyy-MM-dd hh:mm:ss dddd")
self.label_curr.setText("当前时间:"+str_time) str_start = self.start_time.toString("yyyy-MM-dd hh:mm:ss")
str_curr = self.stop_time.toString("yyyy-MM-dd hh:mm:ss")
startTime = datetime.strptime(str_start, "%Y-%m-%d %H:%M:%S")
endTime = datetime.strptime(str_curr, "%Y-%m-%d %H:%M:%S")
seconds = (endTime - startTime).seconds
self.label_total.setText("时间总计:" + str(seconds)+"s") def startTimer(self):
self.start_time = QDateTime.currentDateTime()
str_time = self.start_time.toString("yyyy-MM-dd hh:mm:ss dddd")
self.label_start.setText("开始时间:" + str_time)
self.timer.start(1000)
self.startBtn.setEnabled(False)
self.endBtn.setEnabled(True) def endTimer(self):
self.timer.stop()
self.startBtn.setEnabled(True)
self.endBtn.setEnabled(False) if __name__=="__main__":
app=QApplication(sys.argv)
form=WinTimer()
form.show()

多线程

  假设我们的主界面有一个用于显示时间的 LCD 数字面板和一个用于启动任务的按钮。程序的目的是用户点击按钮,开始一个非常耗时的运算(程序中我们以一个 2000000000 次的循环来替代这个非常耗时的工作,在真实的程序中,这可能是一个网络访问,可能是需要复制一个很大的文件或者其它任务),同时 LCD 开始显示逝去的毫秒数。毫秒数通过一个计时器QTimer进行更新。计算完成后,计时器停止。这是一个很简单的应用,也看不出有任何问题。但是当我们开始运行程序时,问题就来了:点击按钮之后,程序界面直接停止响应,直到循环结束才开始重新更新,于是计时器使用显示0。

  这是因为 Qt 中所有界面都是在 UI 线程中(也被称为主线程,就是执行了QApplication::exec()的线程),在这个线程中执行耗时的操作(比如那个循环),就会阻塞 UI 线程,从而让界面停止响应。界面停止响应,用户体验自然不好,不过更严重的是,有些窗口管理程序会检测到你的程序已经失去响应,可能会建议用户强制停止程序,这样一来程序可能就此终止,任务再也无法完成。所以,为了避免这一问题,我们要使用 QThread 开启一个新的线程:

# coding=utf-8
__author__ = 'a359680405'
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
global sec
sec=0
class WorkThread(QThread):
trigger = pyqtSignal()
def __int__(self):
super(WorkThread,self).__init__() def run(self):
for i in range(203300030):
pass
self.trigger.emit() #循环完毕后发出信号 def countTime():
global sec
sec+=1
lcdNumber.display(sec) #LED显示数字+1 def work():
timer.start(1000) #计时器每秒计数
workThread.start() #计时开始
workThread.trigger.connect(timeStop) #当获得循环完毕的信号时,停止计数 def timeStop():
timer.stop()
print("运行结束用时",lcdNumber.value())
global sec
sec=0
app=QApplication([])
top=QWidget()
layout=QVBoxLayout(top) #垂直布局类QVBoxLayout;
lcdNumber=QLCDNumber() #加个显示屏
layout.addWidget(lcdNumber)
button=QPushButton("测试")
layout.addWidget(button)
timer=QTimer()
workThread=WorkThread()
button.clicked.connect(work)
timer.timeout.connect(countTime) #每次计时结束,触发setTime
top.show()
app.exec()

  上述代码增加了一个WorkerThread类。WorkerThread继承自QThread类,重写了其run()函数。可以认为,run()函数就是新的线程需要执行的代码。在这里就是要执行这个循环,然后发出计算完成的信号。而在按钮点击的槽函数中,使用work()中的workThread.start()函数启动一个线程(注意,这里不是run()函数)。再次运行程序,你会发现现在界面已经不会被阻塞了。

PyQt5信号、定时器及多线程的更多相关文章

  1. C#多线程学习之(五)使用定时器进行多线程的自动管理

    本文实例讲述了C#多线程学习之使用定时器进行多线程的自动管理.分享给大家供大家参考.具体分析如下: Timer类:设置一个定时器,定时执行用户指定的函数. 定时器启动后,系统将自动建立一个新的线程,执 ...

  2. [ PyQt入门教程 ] PyQt5信号与槽

    信号和槽是PyQt编程对象之间进行通信的机制.每个继承自QWideget的控件都支持信号与槽机制.信号发射时(发送请求),连接的槽函数就会自动执行(针对请求进行处理).本文主要讲述信号和槽最基本.最经 ...

  3. PyQt5信号与槽详解

    1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...

  4. java定时器和多线程实践记录

    这几天因为需要测试mongodb读写分离的问题,因此写了个定时查询程序,并且用到了多线程,以达到定时启动多个线程查询数据库的效果,下边代码记录备忘: package timmer; import ja ...

  5. pyqt5信号与槽2

    信号和槽与类的属性和方法在层次上是相同的,同属与一个类的特征. 信号的定义由工厂函数生成: signal=PyQt5.QtCore.pyqtSignal(types[, name[, result[, ...

  6. PyQt5信号-槽机制

    signal -> emit -> slot signal.connect(slot) signal.disconnect(slot) 信号 (singal) 可以连接无数多个槽 (slo ...

  7. PyQt5信号与槽关联的两种方式

    目录 通过QtDesigner 手动关联的方式 通过QtDesigner 单击菜单栏切换到信号槽编辑模式 单击控件并拖动鼠标到信号的接收对象上,一般为对话框自己,松开鼠标弹出信号和槽选择框 选中cli ...

  8. Oracle定时器执行多线程

    what里面加下面代码强制执行多线程   begin  execute immediate 'alter session force parallel dml parallel 16';  pkg_s ...

  9. PyQt5信号与槽

    简单使用 可以使用designer的一个模式定义,也可以自己定义,在__init__函数里,self.btn.clicked.connect(self.text.clear). 注意:槽不用加括号,可 ...

随机推荐

  1. Linux系统查毒软件ClamAV (online)

    ClamAV是一个可用于Linux平台上的开源杀毒引擎,可检测木马.病毒.恶意软件和其他恶意的威胁. 官网:http://www.clamav.net/ 一.CentOS环境安装 # yum inst ...

  2. php位运算 与 或 异或 取反

    <?php /** php中有4个位运算,分别是&与 |或 ^异或 ~取反 & 两位全为1,结果为1 | 有一位为1,结果为1 ^ 一个为0,一个为1,结果为1 ~ 取反0-&g ...

  3. idea maven 集成多模块 module

    首先第一步创建 顶级项目  也就是父项目 在创面那部中 不管你勾不勾 create from 那个选项 都无所谓,最终创建的项目要全删的 ,只保留pom.xml 父项目结构 接下来 创建子项目  也是 ...

  4. windows安装centos7子系统

    Windows的Linux子系统(wsl ) 自从有了wsl后,基本上虚拟机都省了,对于离不开Windows的便捷,Linux对开发的友好的人来说,真是一大利器.可惜默认的系统没有centos,幸运的 ...

  5. PCL_common模块api代码解析

    pcl_common库包含大多数PCL库使用的公共数据结构和方法.核心数据结构包括PointCloud类和许多用于表示点.表面法线.RGB颜色值.特征描述符等的点类型.它还包含许多用于计算距离/范数. ...

  6. Faster-RCNN 算法解读(转)

    论文:<Faster R-CNN: Towards Real-Time ObjectDetection with Region Proposal Networks> 摘要:算法主要解决两个 ...

  7. 【分享】Vue 资源典藏(UI组件、开发框架、服务端、辅助工具、应用实例、Demo示例)

    Vue 资源典藏,包括:UI组件 开发框架 服务端 辅助工具 应用实例 Demo示例 element ★11612 - 饿了么出品的Vue2的web UI工具套件 Vux ★7503 - 基于Vue和 ...

  8. C#高阶与初心:(一)List.Add添加的到底是什么?

    前几日与同事讨论一个相对复杂的场景,需要先将中间过程存储在List中,稍后再用.同时程序类的许多线程共用了一个全局变量. 具体来说就是如下代码 ... _order = order1; _list.A ...

  9. 让windows 2003启动后直接进入桌面

    windows 2003启动后进入桌面需要解决的几个问题 1.如何去除掉 ctrl+alt+del的提示界面 2.如何设置自动登录的用户名密码 3.在异常启动时会出现关闭事件跟踪程序 也会导致不能直接 ...

  10. BarTender怎样同时打印自动日期和流水号?

    大多数条形码中都会含有日期和数量信息,而且大部分都是两者兼具.有些使用BarTender软件的小伙伴,不知道怎么同时打印自动日期和流水号,即条形码中兼有自动日期和序列号,且它们都能根据打印的变化而变化 ...