写在前面

此文档仅记录本人遇到的问题及解决办法,并非涵盖所有

最近写一个股价监控小程序,在改进为界面程序后,每次运行到耗时方法时界面就卡死,无响应,花费了很长事件才把问题解决了,记录一下

原因分析

程序在主线程中执行,当主程序中有一个事件比较耗时时,主程序就会等耗时事件处理完才会进行下一步,此时界面就会卡死出现无响应的状态

代码展示

main.py

import sys
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QApplicationimport stock_price_wringif __name__ == '__main__':app = QApplication(sys.argv)mainW = QMainWindow()ui = monitor.Ui_MainWindow()ui.setupUi(mainW)mainW.show()sys.exit(app.exec_())

调用的耗时代码

 def do_monitor(monitor_info, send_mail, authorization, receive_mail):"""预警监控:param monitor_info: 监控条件数据:param send_mail: 发件邮箱:param authorization: 授权码:param receive_mail: 收件邮箱:return: 回显信息"""now_date = datetime.datetime.now().strftime('%Y-%m-%d')for item in monitor_info:info = get_stock_info(item[0])# 判断监控方式if item[2] == 0:# 价格下跌至if float(info['price'][0]) <= item[1]:text = info['time'][0] + '  ' + info['name'][0] + '触发预警条件:股价跌到' + str(item[1]) + '元,提醒您及时关注'send_content = info['name'][0] + '触发预警条件:股价跌到' + str(item[1]) + '元,提醒您及时关注' + '\n\n' + '股票代码:' + info['code'][0] + '\n' + '股票名称:' + info['name'][0] + '\n' + '预警周期:当日' + '\n' + '预警指标:股价' + '\n' + '时\t\t间:' + now_date + ' ' + info['time'][0]res = do_send_mail(send_mail, authorization, receive_mail, send_content)monitor_info.remove(item)return text+'\n'+reselif item[2] == 1:# 价格上涨至if float(info['price'][0]) >= item[1]:text = info['time'][0] + '  ' + info['name'][0] + '触发预警条件:股价涨到' + str(item[1]) + '元,提醒您及时关注'send_content = info['name'][0] + '触发预警条件:股价涨到' + str(item[1]) + '元,提醒您及时关注' + '\n\n' + '股票代码:' + info['code'][0] + '\n' + '股票名称:' + info['name'][0] + '\n' + '预警周期:当日' + '\n' + '预警指标:股价' + '\n' + '时\t\t间:' + now_date + ' ' + info['time'][0]res = do_send_mail(send_mail, authorization, receive_mail, send_content)monitor_info.remove(item)return text+'\n'+reselse:return ''

解决办法

  • 使用多线程

    • 主线程只执行界面显示
    • 子线程中执行耗时任务
  • 构建窗口类
    • 编写事件响应代码
    • 开启线程
    • 接收线程发送的数据
    • 数据回显
  • 构建线程类
    • 执行耗时任务
    • 发送数据给主程序(信号

子线程中定义信号和发送信号

# 实例化一个信号
signal = pyqtSignal(str)# 发送信号
self.signal.emit(text)

主线程中接收信号

# 实例化线程
self.thread = MonitorThread(self)
# 绑定接收线程信号的方法
self.thread.signal.connect(self.receive_signal)def receive_signal(self, text):"""接收子线程传送的数据 回显至浏览框:param text:"""self.textBrowser.append(text)

部分代码展示

代码结构

程序入口

if __name__ == '__main__':log_dir = os.path.join(os.getcwd(), 'log')if not os.path.exists(log_dir):os.mkdir(log_dir)cgitb.enable(format='text', logdir=log_dir)app = QApplication(sys.argv)myWin = MyMainForm()myWin.show()sys.exit(app.exec_())

窗口类

class MyMainForm(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MyMainForm, self).__init__(parent)self.setupUi(self)# 实例化线程self.thread = MonitorThread(self)# 窗口启动自动执行获取配置数据self.read_base_info()# 按钮点击事件self.chooseBtn.clicked.connect(self.choose_file)self.runBtn.clicked.connect(self.start_monitoring)# 接收线程信号,进行数据回显self.thread.signal.connect(self.receive_signal)def read_base_info(self):"""获取基础数据:发件箱,授权码,收件箱"""base_info = pd.read_table('./baseinfo.txt', header=None)self.sendMail.setText(base_info[0][0])self.authorization.setText(base_info[0][1])self.receiveMail.setText(base_info[0][2])def choose_file(self):"""选择预警信息的存储文件 -> Excel"""root = tkinter.Tk()root.withdraw()filepath = filedialog.askopenfilename()self.filePath.setText(filepath)def start_monitoring(self):"""开始监控 启动子线程 调用子线程接收数据的方法"""# 数据整理file_path = self.filePath.text()send_mail = self.sendMail.text()authorization = self.authorization.text()receive_mail = self.receiveMail.text()base_info = {'file_path': file_path,'send_mail': send_mail,'authorization': authorization,'receive_mail': receive_mail}# 调用线程接收主线程传递数据的方法self.thread.accept_info(base_info)# 开启子线程self.thread.start()def receive_signal(self, text):"""接收子线程传送的数据 回显至浏览框:param text:"""self.textBrowser.append(text)

子线程类

class MonitorThread(QThread):# 实例化一个信号signal = pyqtSignal(str)def __init__(self, main_form):super(MonitorThread, self).__init__()self.file_path = ''self.send_mail = ''self.authorization = ''self.receive_mail = ''self.main_form = main_formdef accept_info(self, base_info):"""接收主线程发送的数据:param base_info:"""self.file_path = base_info.get('file_path')self.send_mail = base_info.get('send_mail')self.authorization = base_info.get('authorization')self.receive_mail = base_info.get('receive_mail')def run(self):"""子线程运行方法,执行耗时任务"""# 获取监控信息monitor_info = get_monitor_info(self.file_path)# 循环监控while True:# 调用方法 返回信息text = do_monitor(monitor_info, self.send_mail, self.authorization, self.receive_mail)# 发送信号self.signal.emit(text)time.sleep(1)

python PyQt5程序运行界面无响应相关推荐

  1. python(pyqt5)多线程解决界面无响应

    多线程解决界面无响应多线程解决界面无响应多线程解决界面无响应 def open_train_task():import osos.system(r"E:\kg\TURN-TAP-master ...

  2. Ubuntu16.04 下的网易云出现网络异常、无法播放,界面无响应问题的统一解决

    能够在Linux系统下体验到原生界面的网易云音乐是件不错的事情,但是它总是经常性的出现网络异常,界面无响应的问题 为了听歌的体验,进行深入探究: 首先通过终端启用网易云音乐:sudo netease- ...

  3. coreos安装php,window_win10系统运行wps无响应的解决方案,wps是我们在日常办公中经常会 - phpStudy...

    win10系统运行wps无响应的解决方案 wps是我们在日常办公中经常会使用到的一款软件,其重要性不容小视.不过,很多用户在将wps升级到2016版后,发现在windows10系统下运行wps会出现无 ...

  4. wps服务器无响应是什么原因,windows10系统运行wps无响应的解决方案

    wps是我们在日常办公中经常会使用到的一款软件,其重要性不容小视.不过,很多用户在将wps升级到2016版后,发现在windows10系统下运行wps会出现无响应的问题,这是怎么回事呢?下面,系统城小 ...

  5. Python记录程序运行的时间

    Python记录程序运行的时间 内置模块time包含很多与时间相关函数.我们可通过它获得当前的时间和格式化时间输出. import timestart = time.clock()#当中是你的程序el ...

  6. python 程序运行计时 动态_python中time库clock 使用Python,实现程序运行计时的数码管表示...

    python编程中time模块下的clock()函数怎么用?pr想起现在的孩子在玩荡秋千回想小编们的第一次.高高兴兴的荡秋千.多久都不累 python编程中time模块下的clock()函数怎么用?在 ...

  7. WPS打开显示服务器无响应,win10系统运行WPS无响应的解决方法

    win10系统想必大家都非常熟悉吧,然而有时候可能会碰到win10系统win10系统运行WPS无响应的问题,比如近日有用户到本站反映说win10系统运行WPS无响应的问题,该怎么处理win10系统运行 ...

  8. PeekMessage完美解决MFC主界面无响应

    一般主界面无响应的解决方案是,对于计算量过大的方法,另开工作者线程,如下: MFC支持两种线程:用户界面线程和工作者线程. (1)用户界面线程:通常用于处理用户输入,响应由用户产生的事件和消息.用户界 ...

  9. W7程序计算机面板介绍,win7系统隐藏任意程序运行界面的详细步骤

    win7系统使用久了,好多网友反馈说win7系统隐藏任意程序运行界面的问题,非常不方便.有什么办法可以永久解决win7系统隐藏任意程序运行界面的问题,面对win7系统隐藏任意程序运行界面的图文步骤非常 ...

最新文章

  1. linux上通过lighttpd上跑一个C语言的CGI小页面以及所遇到的坑
  2. position定位说明
  3. 封装各种生成唯一性ID算法的工具类
  4. 单例模式160905
  5. 要成为一个 Java 架构师得学习哪些知识以及方法?
  6. 信息学奥赛一本通(2054:【例3.4】适合晨练)
  7. 【C语言】将两个字符串连接起来
  8. GaussDB(for MySQL)如何在存储架构设计上做到高可靠、高可用
  9. mysql hyperloglog_Redis HyperLogLog
  10. 锤子手机(smartisan t1)如何查看mac地址
  11. 【机房报修管理系统】1.简介篇 机房报修管理系统简介
  12. 第八章笔记[计算机网络]
  13. 【简单易懂的Unity5 Shader着色器入门教程】 笔记
  14. 南京艺术学院计算机作曲,南京艺术学院932主科(上机操作计算机作曲应用)考研复习经验...
  15. 加载大图片,内存溢出问题
  16. Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
  17. Redis热搜关键词加载,建议收藏
  18. 人体行为姿势识别数据集WISDM实践
  19. 苹果进军RISC-V 招聘职位已发布
  20. 鼠标中键按下拖动滚动条(平移视图)

热门文章

  1. C语言编程 5.7 从键盘中输入一个英文字母,如果它是大写则转化为小写。如果它是小写则转化为大写,并将其ASCll码显示到屏幕上。
  2. jquery - 公历转农历方法
  3. android之发送短信的方法研究
  4. 《淘宝店铺营销推广一册通》一1.3 宝贝标题优化
  5. 史上最牛分析MySQL索引机制的实现!不接受反驳!
  6. 【C语言上机练习题目-代码+运行结果】
  7. Java导出超大Excel文件,防止内存溢出
  8. 因为此版本的应用程序不支持其项目类型(.csproj)”之解
  9. linux系统用户默认的shell,linux默认的shell是什么
  10. VRTK_Artificial Rotator(人工旋转器)脚本属性详解