pyqt下多线程使用案例

TequilaSunrise TequilaSunrise     2022-09-07     471

关键词:

程序的主要功能
   1.串口接收数据
   2.解析串口指令帖并得到命令参数
   3。根据命令参数更新GUI
  其中1和2在一个线程,3在一个线程。
指令格式  [int('7e',16),int('7e',16),0,0,0,0,0,0,int('8e',16),int('8e',16)]。中间的为数据,两端为帖头和帧尾,没有加检验。

GUI如图

tmp

  1 ##-*- coding: utf-8-*
  2 #!D:\ProgramData\Anaconda2\python.exe
  3 """
  4 Author : LEON
  5 EMAIL:yangli0534@yahoo.com
  6 程序的主要功能
  7 1.串口接收数据
  8 2.解析串口指令帖并得到命令参数
  9 3。根据命令参数更新GUI
 10 其中1和2在一个线程,3在一个线程
 11 """
 12 import sys
 13 import math
 14 import time
 15 import serial
 16 from PyQt5 import QtCore, QtGui, uic, QtPrintSupport, QtWidgets
 17 import serial.tools.list_ports
 18 from  threading import Thread
 19 from PyQt5.QtCore import *
 20 from PyQt5.QtGui import *
 21 from PyQt5.QtWidgets import *
 22  
 23 
 24 qtCreatorFile = "panel.ui"# GUI file
 25 Ui_MainWindow, QtBaseClass=uic.loadUiType(qtCreatorFile)
 26 
 27 class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
 28     angle = pyqtSignal(dict) # thread signal 
 29     
 30     def __init__(self):
 31          
 32         QtWidgets.QMainWindow.__init__(self)
 33         Ui_MainWindow.__init__(self)
 34         QThread.__init__(self)
 35         # bkg = QtGui.QPalette()
 36         # bkg.setColor(self.backgroundRole(),QColor(192,253,123))
 37         # self.setPalette(bkg)
 38         self.setupUi(self)
 39         self.ser =serial.Serial()#serial port handle
 40         port_list = list(serial.tools.list_ports.comports())#find serial port avaliable
 41         NoSerial = len(port_list)#number of avaliable serial port 
 42         if  NoSerial> 0:
 43             for port in port_list:
 44                 self.comboBox_serial_No.addItem(port[0])#add to comboBox
 45         baudrate = [9600,14400, 19200, 38400, 56000, 57600, 115200]#baudrate
 46         for baud in baudrate:
 47             self.comboBox_serial_baudrate.addItem(str(baud))
 48         self.comboBox_serial_baudrate.setCurrentIndex(len(baudrate)-1)#default baudrate
 49         self.comboBox_serial_No.setCurrentIndex(NoSerial-1)#default port
 50         self.pushButton_open.clicked.connect(self.open)    #serial port open event connted to button clicked
 51         
 52         self.pushButton_send.clicked.connect(self.send)    #send data event
 53         #self.lcdNumber.display(ord('a'))
 54         #self.param = {"p1":0,"p2":0,"p3":0}
 55         self.para1 = 0 # cmd initialization
 56         self.para2 = 0
 57         self.para3 = 0
 58         self.para4 = 0
 59         self.para5 = 0
 60         self.para6 = 0
 61         #self.angle.connect(self.lcdNumber.display)
 62         self.angle.connect(self.paraP)
 63         #self.angle.connect(self.label_3.setText)
 64         self.sec = 0
 65         #self.dial.setValue(90)
 66         #self.label_tip_2.valueChanged.connect(self.dial.setValue())
 67         #self.dial.setFocusPolicy(Qt.StrongFocus)
 68         #self.angle.connect(self.dial.setValue)
 69         #self.dial.valueChanged.connect(self.slider.setValue)
 70         #con = threading.Condition()
 71         #rece=threading.Thread(target=self.receive,args=())
 72         #rece.start()
 73         self.threads =[]
 74         t1 = Thread(target=self.receive)
 75         t1.setDaemon(True) #
 76         t1.start()#start receiving data thread
 77         self.threads.append(t1) 
 78         t2 =Thread(target=self.updateP) 
 79         t2.setDaemon(True)
 80         t2.start() # start update GUI thread
 81         self.threads.append(t2) 
 82         #self.updateP()
 83                     
 84     def open(self):#open serial port
 85         port = self.comboBox_serial_No.currentText()
 86         baudrate = int(self.comboBox_serial_baudrate.currentText())
 87         if not self.ser.isOpen():
 88             #self.label_tip.setText('this port has been opened')
 89             #self.ser.close()
 90             #self.pushButton_open.setText('已断开')
 91             #self.label_tip.setText('closed')
 92         #else:
 93             self.ser = serial.Serial(port, baudrate, timeout = 10)
 94             if self.ser.isOpen():
 95                 self.pushButton_open.setText('已连接')
 96                 self.label_tip.setText('open sucessed!')
 97                 self.ser.write('roger!')
 98             else:
 99                 self.label_tip.setText('open failed!')        
100     def send(self):    #send data
101         if self.ser.isOpen():
102             text = self.lineEdit_sendBuffer.text()
103             self.ser.write(str(text))
104     def receive(self):# receive data from uart and analysis the protocol frame to get the parameter 
105         #, and then emit to main thread
106         #self.sec += 1
107         #self.lcdNumber.display(self.sec)
108         fsm = 0 
109         info = 0
110         while True:
111              if self.ser.isOpen():
112                  try:
113                     text = self.ser.read(1) #read one byte from uart
114                     if not text :
115                          break
116                     else:
117                         #self.label_3.setText(str(fsm))
118                         text = ord(text)
119                         if fsm == 0:#frame analysis FSM
120                             if text ==int('7e',16):
121                                 fsm = 1
122                             else:
123                                 fsm = 0
124                         elif fsm == 1:
125                             info = {"p1":0,"p2":0,"p3":0,"p4":0,"p5":0,"p6":0}
126                             if text ==int('7e',16):
127                                 fsm = 2
128                             else:
129                                 fsm = 0
130                         elif fsm == 2:
131                             info["p1"]=text
132                             fsm = 3
133                         elif fsm == 3:
134                             info["p2"]=text
135                             fsm = 4
136                         elif fsm == 4:
137                             info["p3"]=text
138                             fsm = 5    
139                         elif fsm == 5:
140                             info["p4"]=text
141                             fsm = 6
142                         elif fsm == 6:
143                             info["p5"]=text
144                             fsm = 7
145                         elif fsm == 7:
146                             info["p6"]=text
147                             fsm = 8        
148                         elif fsm == 8:
149                             if text ==int('8e',16):
150                                 fsm = 9
151                             elif text ==int('7e',16):
152                                 fsm = 1
153                             else:
154                                 fsm = 0
155                         elif fsm ==9:
156                             if text ==int('8e',16):
157                                 fsm = 0
158                                 self.angle.emit(dict(info))#emit signal to main programe
159                             elif text ==int('7e',16):
160                                 fsm = 1
161                             else:
162                                 fsm = 0
163                          #self.angle.emit(str(text))
164                          #self.dial.setValue(int(text))
165                          #self.angle.emit(str((text)))
166                          
167                          #self.angle1.emit(int(text))
168                  except:
169                      break
170             
171             #if self.ser.isOpen():
172              # try:
173                 # text = self.ser.read(1) 
174                 # if not text :
175                      # break
176                 # else:
177                     # self.angle.emit(str(ord(text)))
178                     # #self.dial.setValue(int(text))
179                     # #self.angle.emit(str((text)))
180                     
181                     # #self.angle1.emit(int(text))
182              # except:
183                  # break
184     def paraP(self,r_dict):#update GUI
185         self.para1 = r_dict["p1"]*256+r_dict["p2"]
186         self.para2 = r_dict["p3"]*256+r_dict["p4"]
187         self.para3 = r_dict["p5"]*256+r_dict["p6"]
188         #self.para4 = r_dict["p4"]
189         #self.para5 = r_dict["p5"]
190         #self.para6 = r_dict["p6"]
191     def updateP(self):
192         #self.sec += 1
193         #self.lcdNumber.display(self.sec)
194         while True:
195             # if self.sec < 180:
196                 # self.sec += 1
197             # else:
198                 # self.sec = 0
199             #time.sleep(0.5)
200             #print("Thread update--sec="),
201             #print(self.sec),
202             #print("tmp="),
203             time.sleep(1.0/10.00)
204             tmp =str(1.0*self.para1/100.0)
205             self.lcdNumber_2.display(tmp)
206             tmp =str(1.0*self.para2/100.0)
207             self.lcdNumber_3.display(tmp)
208             tmp =str(1.00*self.para3/100.00)
209             self.lcdNumber.display(tmp)
210             #print(tmp)
211             #self.label_tip_3.setText(tmp)
212             #print(len(tmp))
213             #if len(tmp) <4:
214             tmp = int(str(self.para3),10)
215                 #print("Number = "),
216                 #print(tmp)
217                 #self.label_3.setText(str(tmp))
218                 #if tmp > 0 and tmp < 180:
219             self.dial.setValue(tmp)
220                     
221                     
222 if __name__ == "__main__":
223     app = QtWidgets.QApplication(sys.argv)
224     w = MyApp()
225     w.show()
226     #for t in w.threads:
227         #t.setDaemon(True)
228         #t.start()
229     #w.updateP()    
230     # while True:
231         # time.sleep(0.1)
232         # tmp =str(w.label_tip_2.text())
233         # if tmp.isdigit():
234             # tmp = int(tmp,10)
235             # if tmp > 0 and tmp < 180 :
236                  # w.dial.setValue(tmp)
237 #                self.lcdNumber.display(tmp)
238     sys.exit(app.exec_())
239     

opencv-pyqt项目实战(12)项目案例08:多线程视频播放(代码片段)

欢迎关注『OpenCV-PyQT项目实战@Youcans』系列,持续更新中OpenCV-PyQT项目实战(1)安装与环境配置OpenCV-PyQT项目实战(2)QtDesigner和PyUIC快速入门OpenCV-PyQT项目实战(3)信号与槽机制OpenCV-PyQT项目实战࿰... 查看详情

opencv-pyqt项目实战(12)项目案例08:多线程视频播放(代码片段)

欢迎关注『OpenCV-PyQT项目实战@Youcans』系列,持续更新中OpenCV-PyQT项目实战(1)安装与环境配置OpenCV-PyQT项目实战(2)QtDesigner和PyUIC快速入门OpenCV-PyQT项目实战(3)信号与槽机制OpenCV-PyQT项目实战࿰... 查看详情

Linux下多线程服务器的执行模式

】Linux下多线程服务器的执行模式【英文标题】:ExecutionPatterofMulti-ThreadedServeronLinux【发布时间】:2021-06-2123:21:34【问题描述】:我想知道在高性能服务器的请求-响应周期中实现TCP的服务器多线程的执行模式应该是什么(例如使... 查看详情

ubuntu下多线程简单的线程锁抢门票问题(代码片段)

该小程序创建了4个线程作为窗口进行演示抢票,程序中简单的使用pthread_mutex_lock与pthread_mutex_unlock:main.c:1#include<stdio.h>2#include<pthread.h>3#include<stdlib.h>4#include<string.h>5#include<sched.h> 查看详情

pyqt使用线程更新进度条

】pyqt使用线程更新进度条【英文标题】:pyqtupdatingprogressbarusingthread【发布时间】:2019-12-1217:32:25【问题描述】:我想使用线程方法从我的main.py更新进度条。if__name__=="__main__":app=QApplication(sys.argv)uiplot=gui.Ui_MainWindow()Update_Progressbar... 查看详情

pyqt使用线程更新进度条

】pyqt使用线程更新进度条【英文标题】:pyqtupdatingprogressbarusingthread【发布时间】:2019-12-1217:32:25【问题描述】:我想使用线程方法从我的main.py更新进度条。if__name__=="__main__":app=QApplication(sys.argv)uiplot=gui.Ui_MainWindow()Update_Progressbar... 查看详情

如何使用线程自动关闭 PyQt/PySide 窗口?

】如何使用线程自动关闭PyQt/PySide窗口?【英文标题】:Howtoauto-closePyQt/PySidewindowusingthread?【发布时间】:2017-05-3015:55:20【问题描述】:如何让PyQt5窗口在30秒后自动关闭,并且仍然保持窗口响应交互?我正在创建一个休眠30秒的... 查看详情

使用 PyQt5 轻松实现多线程,用于更新 QTextBrowser 内容

】使用PyQt5轻松实现多线程,用于更新QTextBrowser内容【英文标题】:EasyMulti-threadingwithPyQt5,forupdatingQTextBrowsercontents【发布时间】:2019-04-1217:57:27【问题描述】:我在网上发现一些东西表明PyQt5小部件不是线程安全的。其他***答案... 查看详情

pyqt5使用多线程防止卡死

参考技术A下面将这两个循环使用多线程来写,在PyQT5中,使用QThread再次执行文件,不管我们点击哪个按钮,点击多少次在控制台会立刻打印内容且窗口不会出现卡顿,假死。按钮1使用线程锁,按钮2使用信号注意两者的区别,按... 查看详情

如何通过多线程使用socket和pyqt避免数据丢失

】如何通过多线程使用socket和pyqt避免数据丢失【英文标题】:Howtoavoiddatalossusingsocketandpyqtwithmultithread【发布时间】:2020-02-1309:34:50【问题描述】:我不断地同时从多个客户端接收图像到单个服务器。我已经使用pyqt5和QRunnable来实... 查看详情

opencv-pyqt项目实战项目案例02滚动条应用(代码片段)

...盘(QDial)1.5其它输入调节控件2.项目实战:使用滑动槽(QSlider)调节模糊尺度2.1使用QtDesigner开发PyQt5图形界面2.2.项目主程序的开发2.2.1getHorizontalSlide 查看详情

opencv-pyqt项目实战项目案例02滚动条应用(代码片段)

...盘(QDial)1.5其它输入调节控件2.项目实战:使用滑动槽(QSlider)调节模糊尺度2.1使用QtDesigner开发PyQt5图形界面2.2.项目主程序的开发2.2.1getHorizontalSlide 查看详情

opencv-pyqt项目实战项目案例01:图像模糊(代码片段)

...(5)项目案例01图像模糊1.项目需求2.项目分析3.使用QtDesigner开发PyQt5图形界面3.1创建图形窗口(MainWindow)3.2创建菜单对象(menu)3.3创建工具栏对象(menuÿ 查看详情

opencv-pyqt项目实战项目案例03:鼠标定位(代码片段)

...事件的自定义MyLabel类3.项目实战:PyQt鼠标点击定位3.1使用QtDesig 查看详情

opencv-pyqt项目实战项目案例03:鼠标框选(代码片段)

...鼠标事件的自定义MyLabel类3.项目实战:PyQt鼠标框选3.1使用QtDesigner开发Py 查看详情

在 PyQt5 中使用 QThread 运行多个后台线程

】在PyQt5中使用QThread运行多个后台线程【英文标题】:RunningmultiplebackgroundthreadsusingQThreadinPyQt5【发布时间】:2021-08-1114:30:03【问题描述】:调用多个线程时遇到问题。我没有运气。运行第一个定义(procCounter)正常但不显示或运... 查看详情

opencv-pyqt项目实战项目案例03:鼠标框选(代码片段)

...鼠标事件的自定义MyLabel类3.项目实战:PyQt鼠标框选3.1使用QtDesigner开发PyQt5图形界面3.2.项目主程序的开发3.2.1实例化MyLabel类3.2.2框选图像槽函数3.2 查看详情

linux下多线程的操作(代码片段)

线程定义**定义:**线程是轻量级的进程(LWP:lightweightpocess),在Linux环境下线程的本质仍然是进程。在计算机上运行的程序是一组指令及指令参数的组合,指令按照既定的逻辑控制计算机运行。操作系统会以... 查看详情