PyQt5信号、定时器及多线程
信号
信号是用于界面自动变化的一个工具,原理是信号绑定了一个函数,当信号被触发时函数即被调用
举个例子
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信号、定时器及多线程的更多相关文章
- C#多线程学习之(五)使用定时器进行多线程的自动管理
本文实例讲述了C#多线程学习之使用定时器进行多线程的自动管理.分享给大家供大家参考.具体分析如下: Timer类:设置一个定时器,定时执行用户指定的函数. 定时器启动后,系统将自动建立一个新的线程,执 ...
- [ PyQt入门教程 ] PyQt5信号与槽
信号和槽是PyQt编程对象之间进行通信的机制.每个继承自QWideget的控件都支持信号与槽机制.信号发射时(发送请求),连接的槽函数就会自动执行(针对请求进行处理).本文主要讲述信号和槽最基本.最经 ...
- PyQt5信号与槽详解
1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...
- java定时器和多线程实践记录
这几天因为需要测试mongodb读写分离的问题,因此写了个定时查询程序,并且用到了多线程,以达到定时启动多个线程查询数据库的效果,下边代码记录备忘: package timmer; import ja ...
- pyqt5信号与槽2
信号和槽与类的属性和方法在层次上是相同的,同属与一个类的特征. 信号的定义由工厂函数生成: signal=PyQt5.QtCore.pyqtSignal(types[, name[, result[, ...
- PyQt5信号-槽机制
signal -> emit -> slot signal.connect(slot) signal.disconnect(slot) 信号 (singal) 可以连接无数多个槽 (slo ...
- PyQt5信号与槽关联的两种方式
目录 通过QtDesigner 手动关联的方式 通过QtDesigner 单击菜单栏切换到信号槽编辑模式 单击控件并拖动鼠标到信号的接收对象上,一般为对话框自己,松开鼠标弹出信号和槽选择框 选中cli ...
- Oracle定时器执行多线程
what里面加下面代码强制执行多线程 begin execute immediate 'alter session force parallel dml parallel 16'; pkg_s ...
- PyQt5信号与槽
简单使用 可以使用designer的一个模式定义,也可以自己定义,在__init__函数里,self.btn.clicked.connect(self.text.clear). 注意:槽不用加括号,可 ...
随机推荐
- James 如何作为服务在后台启动
james 启动后是在前台运行的,就像你跑一个微服务,前台运行显然不合理,关闭ssh后就会断开,所以我们得配置在后台,使用service配置即可 配置 james/bin 下的phoenix.sh,配 ...
- Gitee vs插件(Gitee Extension for Visual Studio)
Gitee 码云(gitee.com)是开源中国推出的代码托管平台,支持 Git 和 SVN,提供免费的私有仓库托管. https://gitee.com/GitGroup/Gitee.VisualS ...
- [Z] SQL SERVER 的前世今生--各版本功能对比
https://www.cnblogs.com/OwenZeng/p/6813143.html
- SQL Server 中,如何獲得上個月的第一天和最後一天( 帶時間戳)
select DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) --First day of previous month select DATEA ...
- GPRS模块在Linux平台上ppp拨号上网总结与心得
linux平台的ppp拨号上网,(注明:这里只谈命令行拨号,用linux就要习惯和熟练使用命令行) 在网上常见的有三种方式:1.使用智能的ppp拨号软件wvdial:参考案例:本博客的<使用wv ...
- [原]CentOS7安装Rancher2.1并部署kubernetes (三)---解决登录kubernets超时和部署测试Pod和Containter[nginx为例]
################## Rancher v2.1.7 + Kubernetes 1.13.4 ################ ##################### ...
- [原]Jenkins(十八) jenkins再出发之jenkins 内置变量
1.选择一个project的config选项: 2.选择build选项卡,选择Execute Windows batch command 3.会出现一个内置变量的list 连接按钮: 4.list表内 ...
- web.py框架之i18n支持
问题: 在web.py的模板文件中, 如何得到i18n的支持? Solution: 项目目录结构: proj/ |- code.py |- i18n/ |- messages.po |- en_US/ ...
- array_push() 与 $arr[]=$value 的使用场景
在只压入一个元素的时候使用 $arr[] = $value 当可以同时压入多个元素的时候推荐使用 array_push. 注:如果是压入一个元素,使用$arr[]=$value效率高,因为可以节省调用 ...
- 10 windows server 2012R2 发布MVC框架网站注意事项
1:网站编译完成之后,需要发布,网站中应包括的文件有:文件夹(bin,Views,Content等其他网站中涉及到的文件夹)文件(favicon.ico.Web.config.Global.asax) ...