3 Star 2 Fork 0

wytmxutao/Serial

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Serial.py 36.09 KB
一键复制 编辑 原始数据 按行查看 历史
wytmxutao 提交于 2022-05-09 22:03 . fix some bugs
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
# -*- coding: utf-8 -*-
from PyQt5.QtGui import*
from PyQt5.QtCore import*
from PyQt5.QtWidgets import*
from Base import Serial,SerialHandleThread,QTitleButton,QTitleLabel,serial_thread
from PyQt5.QtChart import QChart, QChartView, QDateTimeAxis, QLegendMarker, QLineSeries, QLogValueAxis, QSplineSeries, QValueAxis
import serial.tools.list_ports,threading,time,math,random,os,sqlite3,sys,json
'''
这个程序包含以下几个线程:
1.接收和发送的线程
2.接受传感器的数据的线程
3.传感器数据画图的线程
4.数据库保存的线程
'''
class SerialWindow(QWidget):
def __init__(self):
super(SerialWindow, self).__init__(None, Qt.FramelessWindowHint) # 设置为顶级窗口,无边框
#Qt交互的线程,将接收发送的线程中产生的信息添加到输出界面
self.outshow = serial_thread()
self.outshow._signal.connect(self.update_output_text)
#显示当前时间,可以设置是否显示的按钮
self.set_time = serial_thread()
self.set_time._signal.connect(self.update_time)
#串口处理的串口
self.set_port = serial_thread()
self.set_port._signal.connect(self.update_serial_port)
#设置串口的状态
self.set_status_color = serial_thread()
self.set_status_color._signal.connect(self.update_serial_status)
#设置界面中默认的字体
self.Dfont = QFont("wytmxutao",12)
self.Ffont = QFont("Consolas",9)
#系统主界面控件排布
# 安放标题栏标签
self.initTitleLabel()
self.initLayout() # 设置框架布局
#设置窗口的宽度和长度
self.minWidth = 1366
self.minHeight = 768
self.setMinimumWidth(self.minWidth)
self.setMinimumHeight(self.minHeight)
# 设置widget鼠标跟踪
self.setMouseTracking(True)
self._get_current_time()
# 初始化一些判断标志
self.init_flag()
#主界面的初始化及优化
self._init_main_area()
#窗口的圆角化
# self.RoundWindow()
#接收传感器数据的线程
#传感器数据画图的线程
self._sensor_data_drawing()
#保存数据库的线程
# self._sensor_data_saving()
'''窗口的圆角处理,但是无法和窗口的放大和缩小兼容'''
def RoundWindow(self):
'''实现UI部分的控件'''
#第一部分:实现去除原有的标题栏,并且加入圆角和抗锯齿处理
self.bmp = QBitmap(self.size())
self.bmp.fill()
self.painter = QPainter(self.bmp)
self.painter.setRenderHint(QPainter.Antialiasing,True)
self.painter.setPen(Qt.NoPen)
self.painter.setBrush(Qt.black)
self.painter.drawRoundedRect(self.bmp.rect(),20,20)
self.setMask(self.bmp)
'''标志的初始化,传感器的检测,串口是否连接,数据库连接标志'''
def init_flag(self):
self._if_sensor_checked = False
self._serial_probed_flag = False
self._serial_connect_flag = False
self._database_flag = False
self._open_serial_flag = False
# 设置鼠标跟踪判断扳机默认值
self._move_drag = False
self._bottom_drag = False
self._right_drag = False
self._left_drag = False
self._right_bottom_corner_drag = False
self._left_bottom_corner_drag = False
'''初始化标题栏的操作'''
def initTitleLabel(self):
# 安放标题栏标签
self._TitleLabel = QTitleLabel(self)
self._TitleLabel.setMouseTracking(True) # 设置标题栏标签鼠标跟踪(如不设,则标题栏内在widget上层,无法实现跟踪)
self._TitleLabel.setIndent(10) # 设置标题栏文本缩进
self._TitleLabel.move(0, 0) # 标题栏安放到左上角
self._TitleLabel.setFixedHeight(30)
'''初始化主界面的布局操作'''
def initLayout(self):
# 设置框架布局
self._main_layout = QGridLayout()
self._main_layout.setSpacing(0)
# 顶一个QLabel在竖放框架第一行,以免正常内容挤占到标题范围里
self._main_layout.addWidget(QLabel(),0,0, Qt.AlignLeft)
self.setLayout(self._main_layout)
'''给widget定义一个setTitleAlignment函数,以实现标题栏标签的对齐方式设定'''
def setTitleAlignment(self, alignment):
self._TitleLabel.setAlignment(alignment | Qt.AlignVCenter)
'''给widget定义一个setCloseButton函数,为True时设置一个关闭按钮'''
def setCloseButton(self, bool):
if bool == True:
self._CloseButton = QTitleButton(self)
self._CloseButton.setFixedSize(20,20)
self._CloseButton.setStyleSheet('''background-color:red;border-radius:10px''')
self._CloseButton.setCursor(Qt.PointingHandCursor) # 设置鼠标形状
self._CloseButton.setToolTip("关闭窗口")
self._CloseButton.setMouseTracking(True) # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
self._CloseButton.clicked.connect(self.close) # 按钮信号连接到关闭窗口的槽函数
self._CloseButton.move(20,15)
'''给widget定义一个setMinMaxButtons函数,为True时设置一组最小化最大化按钮'''
def setMinMaxButtons(self, bool):
if bool == True:
self._MinimumButton = QTitleButton(self)
self._MinimumButton.setFixedSize(20,20)
self._MinimumButton.setStyleSheet('''background-color:yellow;border-radius:10px''')
self._MinimumButton.setCursor(Qt.PointingHandCursor) # 设置鼠标形状
self._MinimumButton.setToolTip("最小化")
self._MinimumButton.setMouseTracking(True) # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
self._MinimumButton.clicked.connect(self.showMinimized) # 按钮信号连接到最小化窗口的槽函数
self._MinimumButton.move(50,15)
self._MaximumButton = QTitleButton(self)
self._MaximumButton.setFixedSize(20,20)
self._MaximumButton.setStyleSheet('''background-color:green;border-radius:10px''')
self._MaximumButton.setCursor(Qt.PointingHandCursor) # 设置鼠标形状
self._MaximumButton.setToolTip("最大化")
self._MaximumButton.setMouseTracking(True) # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
self._MaximumButton.clicked.connect(self._changeNormalButton) # 按钮信号连接切换到恢复窗口大小按钮函数
self._MaximumButton.move(80 ,15)
'''切换到恢复窗口大小按钮'''
def _changeNormalButton(self):
try:
self.showMaximized() # 先实现窗口最大化
self._MaximumButton.setToolTip("恢复") # 更改按钮提示
self._MaximumButton.disconnect() # 断开原本的信号槽连接
self._MaximumButton.clicked.connect(self._changeMaxButton) # 重新连接信号和槽
except:
pass
'''切换到最大化按钮'''
def _changeMaxButton(self):
try:
self.showNormal()
self._MaximumButton.setToolTip("最大化")
self._MaximumButton.disconnect()
self._MaximumButton.clicked.connect(self._changeNormalButton)
except:
pass
'''自定义窗口调整大小事件'''
def resizeEvent(self, QResizeEvent):
# 将标题标签始终设为窗口宽度
self._TitleLabel.setFixedWidth(self.width())
self._param_setting.setFixedWidth(int(self.width()*0.45))
# 重新调整边界范围以备实现鼠标拖放缩放窗口大小,采用三个列表生成式生成三个列表
self._left_rect = [QPoint(x, y) for x in range(0, 5)
for y in range(5, self.height() - 5)]
self._right_rect = [QPoint(x, y) for x in range(self.width() - 5, self.width() + 1)
for y in range(5, self.height() - 5)]
self._bottom_rect = [QPoint(x, y) for x in range(5, self.width() - 5)
for y in range(self.height() - 5, self.height() + 1)]
self._right_bottom_corner_rect = [QPoint(x, y) for x in range(self.width() - 5, self.width() + 1)
for y in range(self.height() - 5, self.height() + 1)]
self._left_bottom_corner_rect = [QPoint(x, y) for x in range(0, 5)
for y in range(self.height() - 5, self.height() + 1)]
'''初始化主要的界面及控件的操作'''
def _init_main_area(self):
#两大主要框架,左侧是程序设置相关框架
#串口相关设置
self._param_setting = QWidget()
self._info_output = QWidget()
self._serial = QGroupBox("串口设置")
self._serial_port = QLabel("串口")
self._serial_port_combobox = QComboBox()
self._serial_baudrate = QLabel("比特率")
self._serial_baudrate_input = QComboBox()
self._serial_timedelay = QLabel("延时")
self._serial_timeout_input = QLineEdit()
self._serial_bytes = QLabel("数据位")
self._serial_bytesize_combobox = QComboBox()
self._serial_stopbit = QLabel("停止位")
self._serial_stopbit_combobox = QComboBox()
self._serial_parity = QLabel("校验位")
self._serial_parity_combobox = QComboBox()
self._serial_send_groupbox = QGroupBox("发送窗口")
self._serial_send_button = QPushButton("发送")
self._serial_send_button.clicked.connect(self._send_messages)
self._serial_time_label = QLabel()
self._serial_sendChar = QTextEdit()
self._open_serial_button = QPushButton("打开串口")
self._serial_status_show = QLabel() #显示串口的状态
self._open_serial_button.clicked.connect(self._execute_serial_running)
self._serial_nary_choice = QGroupBox("选择进制")
self._serial_nary_char = QRadioButton("Char")
self._serial_nary_hex = QRadioButton("Hex")
#设置标签文字居中
self._serial_port.setAlignment(Qt.AlignCenter)
self._serial_baudrate.setAlignment(Qt.AlignCenter)
self._serial_timedelay.setAlignment(Qt.AlignCenter)
self._serial_bytes.setAlignment(Qt.AlignCenter)
self._serial_stopbit.setAlignment(Qt.AlignCenter)
self._serial_parity.setAlignment(Qt.AlignCenter)
#窗口设置相关的qss名称设置
self._serial_time_label.setObjectName("TimeShow")
self._serial_send_groupbox.setObjectName("SendInfo")
self._serial_send_button.setObjectName("SendButton")
self._serial.setObjectName("SerialInfo")
self._serial_port.setObjectName("Port")
self._serial_baudrate.setObjectName("Baudrate")
self._serial_timedelay.setObjectName("TimeDelay")
self._serial_bytes.setObjectName("BytesBit")
self._serial_stopbit.setObjectName("StopBit")
self._open_serial_button.setObjectName("OpenSerial")
self._serial_parity.setObjectName("Parity")
self._serial_sendChar.setObjectName("SendChar")
self._serial_port_combobox.setObjectName("PortCombobox")
self._serial_baudrate_input.setObjectName("BaudrateInput")
self._serial_timeout_input.setObjectName("TimeDelayInput")
self._serial_bytesize_combobox.setObjectName("BytesBitCombobox")
self._serial_stopbit_combobox.setObjectName("StopBitCombobox")
self._serial_parity_combobox.setObjectName("ParityCombobox")
self._serial_nary_choice.setObjectName("NaryChoice")
self._serial_nary_char.setObjectName("RadioChar")
self._serial_nary_hex.setObjectName("RadioHex")
#传感器相关设置
self._sensor_setting_groupbox = QGroupBox("传感器设置")
self._weather_sensor_receive = QCheckBox("接收数据")
self._sensor_collect_time_interval = QLabel("时间间隔")
self._sensor_show_picture = QCheckBox("生成图像")
self._sensor_nums = QLabel("传感器数目")
self._sensor_nums_edit = QLineEdit()
self._sensor_collect_time_value = QLineEdit()
#传感器相关设置的qss名称设置
self._sensor_setting_groupbox.setObjectName("SensorSetting")
self._weather_sensor_receive.setObjectName("SensorReceive")
self._sensor_collect_time_interval.setObjectName("SensorTimeInterval")
self._sensor_show_picture.setObjectName("ProductFigure")
self._sensor_nums.setObjectName("SensorQantity")
self._sensor_nums_edit.setObjectName("SensorQantityEdit")
self._sensor_collect_time_value.setObjectName("SensorTimeIntervalEdit")
#串口显示信息的处理
self._other_setting = QGroupBox("显示设置")
self._output_label = QLabel("串口信息")
self._auto_wrap = QCheckBox("自动换行")
self._show_send = QCheckBox("显示发送")
self._show_time = QCheckBox("时间显示")
self._show_figure = QCheckBox("显示图像")
self._show_figure.stateChanged.connect(self._sensor_data_drawing)
self._output_show = QTextEdit()
self._font_setting = QGroupBox("字体输出设置")
self._font_setting.setObjectName("FontSetting")
self._interface_font_setting = QPushButton("主界面字体")
self._interface_font_setting.clicked.connect(self.get_interface_font)
self._figure_font_setting = QPushButton("图像字体")
self._figure_font_setting.clicked.connect(self.get_figure_font)
self._clear_message = QPushButton("清屏数据")
self._clear_message.clicked.connect(self._clear_outshow_area)
#串口显示信息qss的设置
self._output_label.setObjectName("OutputInfo")
self._other_setting.setObjectName("OtherSetting")
self._auto_wrap.setObjectName("AutoWrap")
self._show_send.setObjectName("ShowSend")
self._show_time.setObjectName("ShowTime")
self._show_figure.setObjectName("ShowFigure")
self._interface_font_setting.setObjectName("InterfaceFont")
self._figure_font_setting.setObjectName("FigureFont")
self._clear_message.setObjectName("ClearScreen")
self._font_setting.setObjectName("FontSetting")
self._output_label.setObjectName("OutputLabel")
self._output_show.setObjectName("OutputShow")
#程序部分和信息输出部分的框架布局选择
self._left_main_layout = QGridLayout()
self._output_layout = QVBoxLayout()
self._serial_layout = QGridLayout()
self._serial_send_layout = QGridLayout()
self._other_left_main_layout = QGridLayout()
self._serial_nary_choice_layout = QHBoxLayout()
self._sensor_setting_layout = QGridLayout()
self._font_setting_layout = QVBoxLayout()
#设置各个部分的框架的布局
self._param_setting.setLayout(self._left_main_layout)
self._info_output.setLayout(self._output_layout)
self._serial.setLayout(self._serial_layout)
self._serial_send_groupbox.setLayout(self._serial_send_layout)
self._serial_nary_choice.setLayout(self._serial_nary_choice_layout)
self._sensor_setting_groupbox.setLayout(self._sensor_setting_layout)
self._font_setting.setLayout(self._font_setting_layout)
self._serial_send_layout.addWidget(self._serial_sendChar,0,0)
self._serial_send_layout.addWidget(self._serial_send_button,1,0)
self._serial_send_layout.addWidget(self._serial_time_label,2,0)
#设置串口groupbox的参数和控件的相关参数
self._serial.setFixedWidth(350)
self._serial_baudrate_input.addItems(bitrate for bitrate in \
['50', '75', '110', '134', '150', '200', '300', '600', '1200', '1800', '2400', '4800',
'9600', '19200', '38400', '57600', '115200', '230400', '460800', '500000',
'576000', '921600', '1000000', '1152000', '1500000', '2000000', '2500000',
'3000000', '3500000', '4000000'])
self._serial_bytesize_combobox.addItems([byte for byte in ['5','6','7','8']])
self._serial_stopbit_combobox.addItems([stopbit for stopbit in ['1', '1.5', '2']])
self._serial_parity_combobox.addItems([parity for parity in ['N', 'E', 'O', 'M', 'S']])
#json配置文件中读取setting.json的文件
with open("./setting.json","r") as f:
setting_string = json.load(f)
self._serial_baudrate_input.setCurrentText(setting_string['Serial']["_serial_baudrate"])
self._serial_timeout_input.setText(setting_string['Serial']["_serial_timeout"])
self._serial_bytesize_combobox.setCurrentText(setting_string['Serial']["_serial_bytesize"])
self._serial_stopbit_combobox.setCurrentText(setting_string['Serial']["_serial_stopbit"])
self._serial_parity_combobox.setCurrentText(setting_string['Serial']["_serial_parity"])
self._serial_status_show.setFixedSize(30,30)
#其他设置选项
self._other_setting.setLayout(self._other_left_main_layout)
self._other_left_main_layout.addWidget(self._auto_wrap,0,0,1,1)
self._other_left_main_layout.addWidget(self._show_send,1,0,1,1)
self._other_left_main_layout.addWidget(self._show_time,2,0,1,1)
self._other_left_main_layout.addWidget(self._show_figure,3,0,1,1)
#字体设置和输出屏幕设置
self._font_setting_layout.addWidget(self._interface_font_setting)
self._font_setting_layout.addWidget(self._figure_font_setting)
self._font_setting_layout.addWidget(self._clear_message)
#串口区域添加的容器和控件
self._serial_layout.addWidget(self._serial_port,0,0,1,1)
self._serial_layout.addWidget(self._serial_port_combobox,0,1,1,1)
self._serial_layout.addWidget(self._serial_baudrate,1,0,1,1)
self._serial_layout.addWidget(self._serial_baudrate_input,1,1,1,1)
self._serial_layout.addWidget(self._serial_timedelay,2,0,1,1)
self._serial_layout.addWidget(self._serial_timeout_input,2,1,1,1)
self._serial_layout.addWidget(self._serial_bytes,3,0,1,1)
self._serial_layout.addWidget(self._serial_bytesize_combobox,3,1,1,1)
self._serial_layout.addWidget(self._serial_stopbit,4,0,1,1)
self._serial_layout.addWidget(self._serial_stopbit_combobox,4,1,1,1)
self._serial_layout.addWidget(self._serial_parity,5,0,1,1)
self._serial_layout.addWidget(self._serial_parity_combobox,5,1,1,1)
self._serial_layout.addWidget(self._serial_nary_choice,6,0,1,2)
self._serial_layout.addWidget(self._open_serial_button,7,0,1,1)
self._serial_layout.addWidget(self._serial_status_show,7,1,1,1)
self._serial_nary_choice_layout.addWidget(self._serial_nary_char)
self._serial_nary_choice_layout.addWidget(self._serial_nary_hex)
self._left_main_layout.addWidget(self._serial,0,0,1,1)
self._left_main_layout.addWidget(self._sensor_setting_groupbox,0,1,1,1)
#向传感器设置中添加相关选项
self._sensor_setting_layout.addWidget(self._sensor_collect_time_interval,0,0,1,1)
self._sensor_setting_layout.addWidget(self._sensor_collect_time_value,0,1,1,1)
self._sensor_setting_layout.addWidget(self._sensor_nums,1,0,1,1)
self._sensor_setting_layout.addWidget(self._sensor_nums_edit,1,1,1,1)
self._sensor_setting_layout.addWidget(self._weather_sensor_receive,2,0,1,2)
self._sensor_setting_layout.addWidget(self._sensor_show_picture,3,0,1,2)
self._left_main_layout.addWidget(self._serial_send_groupbox,1,0,2,1)
self._left_main_layout.addWidget(self._other_setting,1,1,1,1)
self._left_main_layout.addWidget(self._font_setting,2,1,1,1)
#添加输出部分的容器
self._output_layout.addWidget(self._output_label)
self._output_layout.addWidget(self._output_show)
self._main_layout.addWidget(self._param_setting,1,0,2,1)
self._main_layout.addWidget(self._info_output,1,1,1,1)
self._serial_status_show.setStyleSheet('''background-color:red;border-radius:15px''')
def _execute_serial_running(self):
'''串口的初始化操作'''
self._serial_init()
'''开启串口的循环检测'''
self.outshow._signal.emit("开始数据发送前务必开启设备......")
self._outshow_serial_thread = threading.Thread(target= self._serial_connect_checking)
self._outshow_serial_thread.setDaemon(True)
self._outshow_serial_thread.start()
def _serial_init(self):
self.outshow._signal.emit("串口初始化进行中......")
#获取当前串口的信息
self.ports = serial.tools.list_ports.comports()
if self.ports:
#设置串口检测标志为True
self._serial_probed_flag = True
self.set_status_color._signal.emit('y')
#检测到串口将串口信息添加到对应的控件中
for port in self.ports:
self.outshow._signal.emit("检测到串口{}!".format(port.name))
self._serial_port_combobox.insertItem(0, port.name)
'''从这里看出需要一个设置好参数之后打开串口的设置'''
#获取当前的串口相关参数
self.port = self._serial_port_combobox.currentText()
self.baudrate = int(self._serial_baudrate_input.currentText())
self.bytesize = int(self._serial_bytesize_combobox.currentText())
self.timeout = int(self._serial_timeout_input.text())
self.stopbits = int(self._serial_stopbit_combobox.currentText())
self.parity = self._serial_parity_combobox.currentText()
#调用自写的串口类来实现串口的连接操作
if self._serial_probed_flag:
self._local_serial = Serial(port=self.port, baudrate=self.baudrate, timeout=self.timeout,
bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits)
#检测串口是否连接是否成功
if self._local_serial.isConnected:
#成功就可以提示串口连接成功并设置串口连接标志为True
self._serial_connect_flag = True
self.set_status_color._signal.emit('g')
self.outshow._signal.emit("串口{}连接成功!".format(self.port))
else:
self.outshow._signal.emit("未检测到串口的连接!")
self.set_status_color._signal.emit('r')
def _serial_connect_checking(self):
#设置这个标志的目的是让程序仅改变一次,避免循环操作
while True:
#循环检测当前的串口情形
self.ports = serial.tools.list_ports.comports()
self.ports_name = [port.name for port in self.ports] #得到串口的实际可用名称
if self.ports: #若检测到串口
if self._serial_port_combobox.count() == 0:
self._serial_probed_flag = False
self.set_status_color._signal.emit('y')
for port in self.ports_name:
self.set_port._signal.emit(port)
self.outshow._signal.emit("检测到串口{}".format(port))
else:
if not self._serial_probed_flag:
self.outshow._signal.emit("未检测到串口!")
self._serial_probed_flag = True
self.set_status_color._signal.emit('r')
if self._serial_port_combobox.count():
self.outshow._signal.emit("串口{}已拔出!".format(self._serial_port_combobox.currentText()))
self._serial_port_combobox.removeItem(0)
self._serial_port_combobox.update()
#循环检测串口连接中间间隔2s
time.sleep(2)
def _sensor_data_drawing(self):
self._init_sensor_draw()
#输出曲线的初始条件
if self._show_figure.isChecked():
self._sensor_data_drawing_init()
self._sensor_timer_init()
self._output_layout.addWidget(self._sensor_picture_label)
self._output_layout.addWidget(self._sensor_data_drawingview)
self._if_sensor_checked = True
if not os.path.exists("sensor_data.db"):
self._sensor_sqlite = '''create table SensorData (TimeLine int primary key, sensordata int)'''
self._sensor_conn = sqlite3.connect("sensor_data.db")
self.c = self._sensor_conn.cursor()
self.c.execute(self._sensor_sqlite)
self._sensor_conn = sqlite3.connect("sensor_data.db")
self.c = self._sensor_conn.cursor()
self._database_flag = True
else:
if self._if_sensor_checked:
self._sensor_picture_label.close()
self._sensor_data_drawingview.close()
self._sensor_conn.close()
self._database_flag = False
def _init_sensor_draw(self):
pass
def _sensor_timer_init(self):
self.sensor_timer = QTimer(self)
self.sensor_timer.timeout.connect(self._sensor_drawline)
self.sensor_timer.start(2000)
def _sensor_data_drawing_init(self):
self._sensor_picture_label = QLabel("图像")
self._sensor_picture_label.setFont(self.Dfont)
self._sensor_data_drawing = QChart()
self._sensor_data_drawing.setTitle("Sensor Data Collect")
self._sensor_data_drawingview = QChartView(self._sensor_data_drawing)
self._sensor_data_drawingview.setRenderHint(QPainter.Antialiasing)
self._sensor_data_drawingview.setStyleSheet('''font-family:"Consolas";border-radius:15px;''')
self._sensor_series = QSplineSeries()
self._sensor_series.setName("data series")
#把曲线添加到Qchart的实例中
self._sensor_data_drawing.addSeries(self._sensor_series)
#声明并初始化axisX和axisY
self._sensor_dtaxisX = QDateTimeAxis()
self._sensor_dtaxisX.setLabelsAngle(45)
self._sensor_vlaxisY = QValueAxis()
#设置坐标轴范围,即时间的显示长度
self._sensor_dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-300*1))
self._sensor_dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0))
self._sensor_vlaxisY.setMin(0)
self._sensor_vlaxisY.setMax(1500)
#设置坐标轴时间样式
self._sensor_dtaxisX.setFormat("mm:ss")
#设置坐标轴上的格点
self._sensor_dtaxisX.setTickCount(6)
self._sensor_vlaxisY.setTickCount(11)
#设置坐标轴名称
self._sensor_dtaxisX.setTitleText("time")
self._sensor_vlaxisY.setTitleText("SensorData")
#设置网格是否显示
self._sensor_vlaxisY.setGridLineVisible(False)
#把坐标轴添加到chart中
self._sensor_data_drawing.addAxis(self._sensor_dtaxisX, Qt.AlignBottom)
self._sensor_data_drawing.addAxis(self._sensor_vlaxisY, Qt.AlignLeft)
#将曲线关联到坐标轴
self._sensor_series.attachAxis(self._sensor_dtaxisX)
self._sensor_series.attachAxis(self._sensor_vlaxisY)
self._sensor_data_drawingview.setChart(self._sensor_data_drawing)
self.set_figure_font(self.Ffont)
def set_figure_font(self,font):
self._sensor_data_drawing.setFont(font)
self._sensor_data_drawing.setTitleFont(font)
self._sensor_dtaxisX.setTitleFont(font)
self._sensor_dtaxisX.setLabelsFont(font)
self._sensor_vlaxisY.setTitleFont(font)
self._sensor_vlaxisY.setLabelsFont(font)
def _sensor_drawline(self):
#获取当前时间
bjtime = QDateTime.currentDateTime()
#更新x轴坐标
self._sensor_dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-100*1))
self._sensor_dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0))
#当曲线上的点超出x轴的范围时,移除最早的点
if self._sensor_series.count()>149:
self._sensor_series.removePoints(0, self._sensor_series.count()-149)
#产生随机数
yint = random.randint(0,1500)
self._sensor_series.append(bjtime.toMSecsSinceEpoch(),yint)
self.outshow._signal.emit(str(yint))
if self._database_flag:
self.c.execute('''insert into SensorData values(?,?)''',(bjtime.toString(),yint))
self._sensor_conn.commit()
print(bjtime.toString(),yint)
def _send_messages(self):
try:
if self._local_serial.isConnected:
if len(self._serial_sendChar.toPlainText())>1:
self.outshow._signal.emit("目前只支持单个字符!")
elif len(self._serial_sendChar.toPlainText())==0:
self.outshow._signal.emit("请输入字符!")
else:
self.send_serial_data_thread = SerialHandleThread(func=self._local_serial.send_data, args=self._serial_sendChar.toPlainText())
self.get_serial_data_thread = SerialHandleThread(func=self._local_serial.get_data,args=[self._show_time.isChecked(), self._show_send.isChecked()])
self.send_serial_data_thread.setDaemon(True)
self.get_serial_data_thread.setDaemon(True)
self.send_serial_data_thread.start()
self.get_serial_data_thread.start()
self.outshow._signal.emit(self.get_serial_data_thread.get_return_value())
except:
self.outshow._signal.emit("请先进行串口初始化!")
def mousePressEvent(self, event):
# 重写鼠标点击的事件
if (event.button() == Qt.LeftButton) and (event.pos() in self._right_bottom_corner_rect):
# 鼠标左键点击右下角边界区域
self._right_bottom_corner_drag = True
event.accept()
elif (event.button() == Qt.LeftButton) and (event.pos() in self._left_bottom_corner_rect):
# 鼠标左键点击左下角边界区域
self._left_bottom_corner_drag = True
event.accept()
elif (event.button() == Qt.LeftButton) and (event.pos() in self._left_rect):
# 鼠标左键点击左侧边界区域
self._left_drag = True
event.accept()
elif (event.button() == Qt.LeftButton) and (event.pos() in self._right_rect):
# 鼠标左键点击右侧边界区域
self._right_drag = True
event.accept()
elif (event.button() == Qt.LeftButton) and (event.pos() in self._bottom_rect):
# 鼠标左键点击下侧边界区域
self._bottom_drag = True
event.accept()
elif (event.button() == Qt.LeftButton) and (event.y() < self._TitleLabel.height()):
# 鼠标左键点击标题栏区域
self._move_drag = True
self.move_DragPosition = event.globalPos() - self.pos()
event.accept()
def mouseMoveEvent(self, QMouseEvent):
# 判断鼠标位置切换鼠标手势
if QMouseEvent.pos() in self._right_bottom_corner_rect:
self.setCursor(Qt.SizeFDiagCursor)
elif QMouseEvent.pos() in self._left_bottom_corner_rect:
self.setCursor(Qt.SizeBDiagCursor)
elif QMouseEvent.pos() in self._bottom_rect:
self.setCursor(Qt.SizeVerCursor)
elif QMouseEvent.pos() in self._right_rect:
self.setCursor(Qt.SizeHorCursor)
elif QMouseEvent.pos() in self._left_rect:
self.setCursor(Qt.SizeHorCursor)
else:
self.setCursor(Qt.ArrowCursor)
# 当鼠标左键点击不放及满足点击区域的要求后,分别实现不同的窗口调整
if Qt.LeftButton and self._right_drag:
# 右侧调整窗口宽度
self.resize(QMouseEvent.pos().x(), self.height())
QMouseEvent.accept()
elif Qt.LeftButton and self._left_drag:
# 左侧调整窗口高度
if self.width() - QMouseEvent.pos().x() > self.minWidth:
self.resize(self.width() - QMouseEvent.pos().x(), self.height())
self.move(self.x() + QMouseEvent.pos().x(), self.y())
QMouseEvent.accept()
elif Qt.LeftButton and self._bottom_drag:
# 下侧调整窗口高度
self.resize(self.width(), QMouseEvent.pos().y())
QMouseEvent.accept()
elif Qt.LeftButton and self._right_bottom_corner_drag:
# 右下角同时调整高度和宽度
self.resize(QMouseEvent.pos().x(), QMouseEvent.pos().y())
QMouseEvent.accept()
elif Qt.LeftButton and self._left_bottom_corner_drag:
# 左下角同时调整高度和宽度
if self.width() - QMouseEvent.pos().x() > self.minWidth:
self.resize(self.width() - QMouseEvent.pos().x(), QMouseEvent.pos().y())
self.move(self.x() + QMouseEvent.pos().x(), self.y())
QMouseEvent.accept()
elif Qt.LeftButton and self._move_drag:
# 标题栏拖放窗口位置
self.move(QMouseEvent.globalPos() - self.move_DragPosition)
QMouseEvent.accept()
def mouseReleaseEvent(self, QMouseEvent):
# 鼠标释放后,各扳机复位
self._move_drag = False
self._right_bottom_corner_drag = False
self._bottom_drag = False
self._right_drag = False
self._left_drag = False
self._left_bottom_corner_drag = False
def update_output_text(self,s):
if self._auto_wrap.isChecked():
if self._show_time.isChecked():
self._output_show.append(self._current_time+":["+s+"]")
else:
self._output_show.append(s)
else:
if self._show_time.isChecked():
self._output_show.moveCursor(QTextCursor.End)
self._output_show.insertPlainText(" ")
self._output_show.insertPlainText(self._current_time+":["+s+"]")
else:
self._output_show.moveCursor(QTextCursor.End)
self._output_show.insertPlainText(" ")
self._output_show.insertPlainText(s)
def update_time(self,s):
self._serial_time_label.setText(s)
def update_serial_port(self,s):
self._serial_port_combobox.addItem(s)
def update_serial_status(self,s):
if s == 'r':
self._serial_status_show.setStyleSheet("background-color:rgb(255,0,0);border-radius:15px;")
elif s == 'y':
self._serial_status_show.setStyleSheet("background-color:rgb(255,255,0);border-radius:15px;")
elif s== 'g':
self._serial_status_show.setStyleSheet("background-color:rgb(0,255,0);border-radius:15px;")
else:
pass
def _clear_outshow_area(self):
self._output_show.clear()
def get_interface_font(self):
font, ok = QFontDialog.getFont()
if ok:
#通过修改qss配置文件来修改字体,临时修改使用
with open('./Serial.qss',encoding='utf-8') as f:
qssfile = f.read().replace("方正苏新诗柳楷简体",font.toString().split(",")[0])
self.setStyleSheet(qssfile)
def get_figure_font(self):
font, ok = QFontDialog.getFont()
if ok:
self.set_figure_font(font)
def _get_current_time(self):
def get_now():
while True:
struct_time = time.localtime(time.time())
self._current_time = time.strftime("%Y-%m-%d %H:%M:%S",struct_time)
time.sleep(1)
#设置界面上的时间的持续显示
self.set_time._signal.emit(self._current_time)
self.get_time_thread = threading.Thread(target=get_now)
self.get_time_thread.setDaemon(True)
self.get_time_thread.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SerialWindow()
window.setCloseButton(True)
window.setMinMaxButtons(True)
with open("./Serial.qss",encoding='utf-8') as f:
qssfile = f.read()
window.setStyleSheet(qssfile)
window.show()
sys.exit(app.exec_())
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/niko_xu_tao/Serial.git
git@gitee.com:niko_xu_tao/Serial.git
niko_xu_tao
Serial
Serial
master

搜索帮助