[白月黑羽]关于风机协议工具的解答

架构 python3.8+pyqt5
先来看下原题:
在这里插入图片描述
视频中软件的效果
在这里插入图片描述
先来看下程序的效果如何,看上去大概相似
在这里插入图片描述
对应代码已经上传到了gitcode
https://gitcode.com/m0_37662818/fan_protocol_tool/overview

实现中的难点是双悬浮可视化,同时要高亮悬浮对应内容,程序中用的的事件过滤器。也许白月黑羽用的是更好的方法。

代码如下
app.py 主文件

from PyQt5 import QtWidgets,QtCore,QtGui
from ui_main import Ui_MainWindow  # 导入主界面类
import sys
import socket
import traceback 
from typing import List, Tuple
      
class MySignal(QtCore.QObject):
    update_sheet = QtCore.pyqtSignal(str)
    hover_signal = QtCore.pyqtSignal(int)
my_signal = MySignal()

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)  # 加载主界面
        self.socket_fan = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建socket对象
        self.ui.btn_connect_server.clicked.connect(self.connect_fan)  # 绑定按钮事件
        self.ui.stackedWidget.setCurrentIndex(0)
        self.ui.msg_list.setFlow(QtWidgets.QListView.Flow.LeftToRight)
        self.ui.msg_list.setViewMode(QtWidgets.QListView.ViewMode.IconMode)
        self.ui.msg_list.setResizeMode(QtWidgets.QListView.ResizeMode.Adjust)
        self.ui.msg_list.setWrapping(True)
        self.ui.msg_list.setSpacing(3)

        self.ui.msg_head_list.setFlow(QtWidgets.QListView.Flow.LeftToRight)
        self.ui.msg_head_list.setWrapping(True)
        self.ui.msg_head_list.setViewMode(QtWidgets.QListView.ViewMode.IconMode)
        self.ui.msg_head_list.setResizeMode(QtWidgets.QListView.ResizeMode.Adjust)

        self.ui.msg_head_list.setFixedHeight(70)

        self.ui.msg_list.setDragEnabled(False)
        self.ui.msg_head_list.setDragEnabled(False)
        self.ui.msg_body_table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Stretch)
        self.ui.msg_body_table.verticalHeader().hide()
        self.ui.msg_body_table.horizontalHeader().setStyleSheet("color:#00789d;")

        self.ui.msg_list.setAttribute(QtCore.Qt.WidgetAttribute.WA_Hover,True)
        self.ui.msg_body_table.setAttribute(QtCore.Qt.WidgetAttribute.WA_Hover,True)
        self.ui.msg_head_list.setAttribute(QtCore.Qt.WidgetAttribute.WA_Hover,True)
        
        self.ui.msg_list.installEventFilter(self)
        self.ui.msg_body_table.installEventFilter(self)
        self.ui.msg_head_list.installEventFilter(self)

        self.last_hover_index = -1
        self.msg_id = 0

        self.ui.listWidget.itemClicked.connect(self.list_widget_clicked)
        self.ui.btn_set.clicked.connect(self.btn_set_clicked)
        self.ui.btn_get_sn.clicked.connect(self.btn_get_sn_clicked)
        self.ui.btn_get_state.clicked.connect(self.btn_get_state_clicked)

        my_signal.update_sheet.connect(self.update_sheet_cb)
        my_signal.hover_signal.connect(self.draw_cb)

    def draw_cb(self,index):
        def draw_(index:int,color:str):
            self.ui.msg_list.item(index).setBackground(QtGui.QColor(color))
            if index < 3:
                self.ui.msg_head_list.item(index * 2 + 1).setBackground(QtGui.QColor(color))
            else:
                row = index//3 - 1
                col = index%3 + 1
                self.ui.msg_body_table.item(row,col).setBackground(QtGui.QColor(color))

        if(index == self.last_hover_index):
            return
        if(self.last_hover_index != index):
            if(self.last_hover_index >= 0):
                draw_(self.last_hover_index,'white')
            if(index >= 0):
                draw_(index,'orangered')

        if(index < 0 and self.last_hover_index >= 0):
            draw_(self.last_hover_index,'white')
        self.last_hover_index = index

    def eventFilter(self, watched:QtWidgets.QWidget, event:QtCore.QEvent):
        
        if(watched == self.ui.msg_head_list):
        
            if(event.type() == QtCore.QEvent.Type.HoverMove):
                index = watched.indexAt(event.pos()).row()
                my_signal.hover_signal.emit(index//2)
            if(event.type() == QtCore.QEvent.Type.HoverLeave):
                my_signal.hover_signal.emit(-1)

        if(watched == self.ui.msg_list):
            if(event.type() == QtCore.QEvent.Type.HoverMove):
                index = watched.indexAt(event.pos()).row()
                my_signal.hover_signal.emit(index)
            if(event.type() == QtCore.QEvent.Type.HoverLeave):
                my_signal.hover_signal.emit(-1)
        
        if(watched == self.ui.msg_body_table):
            if(event.type() == QtCore.QEvent.Type.HoverMove):
                x = event.pos().x()
                y = event.pos().y()
                
                hight = watched.horizontalHeader().height()
                point = QtCore.QPoint(x,y - hight)
                Model_index = watched.indexAt(point)
                p = event.pos()

                
                if Model_index is None:
                    my_signal.hover_signal.emit(-1)
                
                else:
                    index = -1
                    row = Model_index.row()
                    col = Model_index.column()
                    if(row >= 0 and col >= 1):
                        row = Model_index.row()
                        #print("row:" + str(row))
                        col = Model_index.column()
                        #print("col:" + str(col))
                        index = (row) * 3 + col - 1 + 3
                    my_signal.hover_signal.emit(index) 
            if(event.type() == QtCore.QEvent.Type.HoverLeave):
                my_signal.hover_signal.emit(-1)

        return super().eventFilter( watched, event)       

    def update_sheet_cb(self,text:str):
        def fill_data(infos:List[Tuple[str,str]]):
            for index,info in enumerate(infos):
                self.ui.msg_list.addItem(info[0])
                if index < 3:
                    if index == 0:
                        self.ui.msg_head_list.addItem("消息长度:")
                    if index == 1: 
                        self.ui.msg_head_list.addItem("类型:")
                    if index == 2:
                        self.ui.msg_head_list.addItem("消息ID:")
                    self.ui.msg_head_list.addItem(str(info[1]))
                elif index % 3 == 0:
                    self.ui.msg_body_table.insertRow(index // 3 - 1)
                    table_item = QtWidgets.QTableWidgetItem(str(infos[index][1]))
                    table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    self.ui.msg_body_table.setItem(index // 3 - 1, 1, table_item)

                    table_item = QtWidgets.QTableWidgetItem(str(infos[index + 1][1]))
                    table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    self.ui.msg_body_table.setItem(index // 3 - 1, 2, table_item)

                    table_item = QtWidgets.QTableWidgetItem(str(infos[index + 2][1]))
                    table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    self.ui.msg_body_table.setItem(index // 3 - 1, 3, table_item)

                    if infos[index][0] == "01":
                        table_item = QtWidgets.QTableWidgetItem("设备编号")
                        table_item.setForeground(QtGui.QColor(255,128,0))
                        table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                        self.ui.msg_body_table.setItem(index // 3 - 1, 0, table_item)
                    elif infos[index][0] == "02":

                        table_item = QtWidgets.QTableWidgetItem("设备状态")
                        table_item.setForeground(QtGui.QColor(255,128,0))
                        table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                        self.ui.msg_body_table.setItem(index // 3 - 1, 0,table_item)
                    elif infos[index][0] == "a0":

                        table_item = QtWidgets.QTableWidgetItem("结果码")
                        table_item.setForeground(QtGui.QColor(255,128,0))
                        table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                        self.ui.msg_body_table.setItem(index // 3 - 1, 0,table_item)
                    elif infos[index][0] == "a1":

                        table_item = QtWidgets.QTableWidgetItem("结果描述")
                        table_item.setForeground(QtGui.QColor(255,128,0))
                        table_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                        self.ui.msg_body_table.setItem(index // 3 - 1, 0, table_item)
                    
            #上色
            for i in range(self.ui.msg_list.count()):
                if i < 3:
                    self.ui.msg_list.item(i).setForeground(QtGui.QColor(0,128,0))
                elif i % 3 == 0:
                    self.ui.msg_list.item(i).setForeground(QtGui.QColor(255,128,0))
                elif i % 3 == 1:
                    self.ui.msg_list.item(i).setForeground(QtGui.QColor(0, 120, 157))
                
                
            pass
        
        res = bytes.fromhex(text)
        infos = self.resolve_response(res)
        self.ui.msg_list.clear()
        self.ui.msg_head_list.clear()
        self.ui.msg_body_table.setRowCount(0)
        fill_data(infos)

        pass
    
    def connect_fan(self):
        
        ip = self.ui.input_server_ip.text()
        port = int(self.ui.input_server_port.text())
        print(ip, port)
        if not ip or not port:
            self.ui.msgWindow.append("请输入风机IP和端口!")
            return
        if self.ui.btn_connect_server.text() == "连接":
            try:
                self.socket_fan.connect((ip, port))  # 连接风机
                self.ui.msgWindow.append("连接风机成功!")
                #self.ui.btn_connect_server.setText("断开")
            except Exception as error:
                self.ui.msgWindow.append("连接风机失败!")
                print(error)
        elif self.ui.btn_connect_server.text() == "断开":
            self.socket_fan.close()  # 断开连接
            self.ui.msgWindow.append("断开风机连接!")
            self.ui.btn_connect_server.setText("连接")

    def btn_set_clicked(self):
        text = self.ui.btn_set.text()
        if(text == '设置'):
            self.set_dev_stats_process()

    def btn_get_sn_clicked(self):
        self.get_dev_stats_process(state=1)

    def btn_get_state_clicked(self):
        self.get_dev_stats_process(state=2)


    def list_widget_clicked(self,item:QtWidgets.QListWidgetItem):
        text = item.text()
        if(text == "连接设备"):
            self.change_page_connect()
        elif(text == "设置风泵状态"):
            self.change_page_set()
        elif(text == "读取风泵状态"):
            self.change_page_get()


    def change_page_connect(self):
        self.ui.stackedWidget.setCurrentIndex(0)
    def change_page_set(self):
        self.ui.stackedWidget.setCurrentIndex(1)
    def change_page_get(self):
        self.ui.stackedWidget.setCurrentIndex(2)

    # 获取设备配置请求
    def get_dev_config_request(self,msg_id:int,state:int)-> bytes:
        body = b''
        body += b'\xC1'
        body += b'\x03'
        body += (state.to_bytes(1,byteorder='big'))
        msg_len = 8 + len(body)
        msg_type = 0x01F0
        msg_id = msg_id
        return msg_len.to_bytes(2,byteorder='big') + msg_type.to_bytes(2,byteorder='big') + msg_id.to_bytes(4,byteorder='big') + body

    # 获取设备配置通信过程
    def get_dev_stats_process(self,state=0):
        msg_id = self.msg_id

        try:
            req = self.get_dev_config_request(msg_id, state)
            self.socket_fan.send(req)
            self.ui.msgWindow.append("发送消息:")
            self.ui.msgWindow.append("<font color=\"#006400\">"+ req.hex() + "</font> ")
            res =  self.socket_fan.recv(1024)
            self.ui.msgWindow.append("接收消息:")
            self.ui.msgWindow.append("<font color=\"#006400\">"+ res.hex() + "</font> ")

            infos = self.resolve_response(res)
            for index,info in enumerate(infos):
                if index == 3 or index == 6:
                    if info[0] == "01":
                        self.ui.output_devSn.setText(str(infos[index + 2][1]))
                    elif info[0] == "02":
                        self.ui.output_devState.setText(str(infos[index + 2][1]))
            my_signal.update_sheet.emit(res.hex())
        except Exception as e:
            traceback.print_exc()
        
        self.msg_id += 1
        
        pass

    # 组装设备配置请求
    def set_dev_config_request(self,msgid:int,dev:str, stats:int):
        body = b''

        if dev is not None:
            body += b'\x01'
            body += (len(dev) + 2).to_bytes(1,byteorder='big')
            body += dev.encode()
        if stats is not None:
            body += b'\x02'
            body += (3).to_bytes(1,byteorder='big')
            body += stats.to_bytes(1,byteorder='big')
        msg_len = 8 + len(body)
        msg_type = b'\x02\xF0'
        msgid = msgid
        return msg_len.to_bytes(2,byteorder='big') + msg_type + msgid.to_bytes(4,byteorder='big') + body

    # 设置设备状态通信过程
    def set_dev_stats_process(self):
        msg_id = self.msg_id
        dev_id_text =  self.ui.input_devSn.text() if len(self.ui.input_devSn.text()) > 0 else  None
        dev_stats_text = self.ui.input_devState.text()
        dev_stats = None
        if dev_stats_text is not None and len(dev_stats_text) != 0 :
            dev_stats = int(dev_stats_text)

        try:
            req = self.set_dev_config_request(msgid=msg_id,dev = dev_id_text,stats=dev_stats)
            self.socket_fan.send(req)
            self.ui.msgWindow.append("发送消息:")
            self.ui.msgWindow.append("<font color=\"#006400\">"+ req.hex() + "</font> ")
            res =  self.socket_fan.recv(1024)
            self.ui.msgWindow.append("接收消息:")
            self.ui.msgWindow.append("<font color=\"#006400\">"+ res.hex() + "</font> ")
            my_signal.update_sheet.emit(res.hex())
        except Exception as e:
            traceback.print_exc()
        
        self.msg_id += 1
        pass

    # 解析响应 bytes版
    '''
    def resolve_response(self, res:bytes)-> dict:
        if len(res) < 8:
            return {}
        infos = {}
        msg_type_bytes = res[2:4]
        msg_type = 'unknown massage '

        if msg_type_bytes == b'\x01\xF1':
            msg_type = 'read state response'
        elif msg_type_bytes == b'\x02\xF1':
            msg_type = 'set state response'

        infos["msg_len"] = int.from_bytes(res[0:2],byteorder='big') 
        infos["msg_id"] =  int.from_bytes(res[4:8],byteorder='big')
        infos["msg_type"] = msg_type
        pos = 8
        while pos < len(res):
            code = res[pos:pos + 1]
            if(msg_type_bytes == b'\x01\xF1'):
                
                if code == b'\x01':
                    length = res[pos + 1]
                    desc = res[pos+2:pos+length].decode()
                    field = Field(b'\x01',length,desc)
                    infos['sn'] = field
                    pos += length
                elif code == b'\x02':
                    length = res[pos + 1]
                    desc = int.from_bytes(res[pos + 2:pos + length],byteorder='big')
                    field = Field(b'\x02',length,desc)
                    infos['state'] = field
                    pos += length
                else:
                    break
            if(msg_type_bytes == b'\x02\xF1'):
                if code == b'\xA0':
                    length = res[pos + 1]
                    desc = int.from_bytes[pos + 2: pos + length]
                    field = Field(b'\xA0',length,desc)
                    infos['code'] = field
                    pos += length
                elif code == b'\xA1':
                    length = res[pos + 1]
                    desc = res[pos+2:pos + length].decode()
                    field = Field(b'\xA1',length,desc)
                    infos['desc'] = field
                    pos += length
                else:
                    break
        return infos

        pass
    '''

    # 解析响应 str版
    def resolve_response(self, res:bytes)-> list:
        def resolve_response_head(res_head:bytes)->list:
            infos = []
            msg_type = 0
            msg_len_hex = (res_head[0:2]).hex()
            msg_type_hex = (res_head[2:4]).hex()
            msg_id_hex = (res_head[4:8]).hex()
            msg_type_desc = ""

            msg_len = int.from_bytes(res_head[0:2],byteorder='big')
            msg_id = int.from_bytes(res_head[4:8],byteorder='big')

            if(msg_type_hex.upper() == "01F1"):
                    msg_type_desc = "get_state_response"
            elif(msg_type_hex.upper() == "02F1"):
                    msg_type_desc = "set_state_response"

            infos.append((msg_len_hex,msg_len))
            infos.append((msg_type_hex,msg_type_desc))
            infos.append((msg_id_hex,msg_id))
            return infos

        def resolve_response_body_get_state(res_body:bytes)->list:
            pos = 0
            infos = []
            while pos < len(res_body):
                code_hex = res_body[pos:pos + 1].hex()
                length_hex = res_body[pos + 1:pos + 2].hex()
                length = res_body[1]
                value_hex = res_body[pos + 2: pos + length].hex()
                value = ""
                if(code_hex == "01"):
                    value = res_body[pos + 2:pos + length].decode(encoding="ANSI")
                elif(code_hex == "02"):
                    value = int.from_bytes(res_body[pos + 2:pos + length],byteorder='big')
                infos.append((code_hex,code_hex))
                infos.append((length_hex,str(length)))
                infos.append((value_hex,str(value)))
                pos += length
            return infos

        def resolve_response_body_set_state(res_body:bytes)->list:
            pos = 0
            infos = []
            while pos < len(res_body):
                code_hex = res_body[pos:pos + 1].hex()
                length_hex = res_body[pos + 1:pos + 2].hex()
                length = res_body[pos+1]
                value_hex = res_body[pos + 2:pos + length].hex()
                value = ""
                if(code_hex.upper() == "A0"):
                    value = res_body[pos+2]
                elif(code_hex.upper() == "A1"):
                    value = res_body[pos + 2:pos + length].decode(encoding="ANSI")
                infos.append((code_hex,code_hex))
                infos.append((length_hex,str(length)))  
                infos.append((value_hex,str(value)))
                pos += length
            return infos

        res_len = len(res)
        if res_len < 8:
            return []
        msg_len = int.from_bytes(res[0:2],byteorder='big')
        if msg_len > res_len:
            return []
        res_head = res[0:8]
        res_body = res[8:msg_len]
        infos = []
        infos = resolve_response_head(res_head)
        if(infos[1][0].upper() == "01F1"):
            infos = infos + resolve_response_body_get_state(res_body)
        elif(infos[1][0].upper() == "02F1"):
            infos = infos + resolve_response_body_set_state(res_body)
        return infos

if __name__ == '__main__':
    app = QtWidgets.QApplication([])  # 创建QApplication对象
    window = MainWindow()  # 创建主界面对象
    window.show()  # 显示主界面
    sys.exit(app.exec_())  # 运行主界面

ui_main.py 文件

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'main.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(593, 600)
        MainWindow.setStyleSheet("* { \n"
"    color: rgb(88, 88, 88);\n"
" font-size:14px;\n"
" font-family: consolas, \"微软雅黑\";\n"
"}")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth())
        self.listWidget.setSizePolicy(sizePolicy)
        self.listWidget.setStyleSheet("\n"
"\n"
"QListWidget::item:selected\n"
"{\n"
"    background: #f5d6db;\n"
"    color: rgb(83, 83, 83);\n"
"}\n"
"")
        self.listWidget.setObjectName("listWidget")
        item = QtWidgets.QListWidgetItem()
        self.listWidget.addItem(item)
        item = QtWidgets.QListWidgetItem()
        self.listWidget.addItem(item)
        item = QtWidgets.QListWidgetItem()
        self.listWidget.addItem(item)
        self.horizontalLayout_3.addWidget(self.listWidget)
        self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.stackedWidget.sizePolicy().hasHeightForWidth())
        self.stackedWidget.setSizePolicy(sizePolicy)
        self.stackedWidget.setLineWidth(0)
        self.stackedWidget.setObjectName("stackedWidget")
        self.page = QtWidgets.QWidget()
        self.page.setObjectName("page")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.page)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.label = QtWidgets.QLabel(self.page)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.input_server_ip = QtWidgets.QLineEdit(self.page)
        self.input_server_ip.setObjectName("input_server_ip")
        self.horizontalLayout.addWidget(self.input_server_ip)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem2)
        self.label_2 = QtWidgets.QLabel(self.page)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_2.addWidget(self.label_2)
        self.input_server_port = QtWidgets.QLineEdit(self.page)
        self.input_server_port.setObjectName("input_server_port")
        self.horizontalLayout_2.addWidget(self.input_server_port)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem3)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem4)
        self.btn_connect_server = QtWidgets.QPushButton(self.page)
        self.btn_connect_server.setObjectName("btn_connect_server")
        self.horizontalLayout_7.addWidget(self.btn_connect_server)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem5)
        self.verticalLayout.addLayout(self.horizontalLayout_7)
        self.stackedWidget.addWidget(self.page)
        self.page_2 = QtWidgets.QWidget()
        self.page_2.setObjectName("page_2")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page_2)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem6)
        self.label_3 = QtWidgets.QLabel(self.page_2)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_8.addWidget(self.label_3)
        self.input_devSn = QtWidgets.QLineEdit(self.page_2)
        self.input_devSn.setObjectName("input_devSn")
        self.horizontalLayout_8.addWidget(self.input_devSn)
        spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem7)
        self.verticalLayout_3.addLayout(self.horizontalLayout_8)
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
        spacerItem8 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_10.addItem(spacerItem8)
        self.label_4 = QtWidgets.QLabel(self.page_2)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_10.addWidget(self.label_4)
        self.input_devState = QtWidgets.QLineEdit(self.page_2)
        self.input_devState.setStyleSheet("")
        self.input_devState.setObjectName("input_devState")
        self.horizontalLayout_10.addWidget(self.input_devState)
        spacerItem9 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_10.addItem(spacerItem9)
        self.verticalLayout_3.addLayout(self.horizontalLayout_10)
        self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
        spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_9.addItem(spacerItem10)
        self.btn_set = QtWidgets.QPushButton(self.page_2)
        self.btn_set.setObjectName("btn_set")
        self.horizontalLayout_9.addWidget(self.btn_set)
        spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_9.addItem(spacerItem11)
        self.verticalLayout_3.addLayout(self.horizontalLayout_9)
        self.stackedWidget.addWidget(self.page_2)
        self.page_3 = QtWidgets.QWidget()
        self.page_3.setObjectName("page_3")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.page_3)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_12.addItem(spacerItem12)
        self.label_6 = QtWidgets.QLabel(self.page_3)
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_12.addWidget(self.label_6)
        self.output_devSn = QtWidgets.QLineEdit(self.page_3)
        self.output_devSn.setObjectName("output_devSn")
        self.horizontalLayout_12.addWidget(self.output_devSn)
        spacerItem13 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_12.addItem(spacerItem13)
        self.verticalLayout_4.addLayout(self.horizontalLayout_12)
        self.horizontalLayout_11 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
        spacerItem14 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_11.addItem(spacerItem14)
        self.label_5 = QtWidgets.QLabel(self.page_3)
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_11.addWidget(self.label_5)
        self.output_devState = QtWidgets.QLineEdit(self.page_3)
        self.output_devState.setStyleSheet("")
        self.output_devState.setObjectName("output_devState")
        self.horizontalLayout_11.addWidget(self.output_devState)
        spacerItem15 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_11.addItem(spacerItem15)
        self.verticalLayout_4.addLayout(self.horizontalLayout_11)
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
        spacerItem16 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_13.addItem(spacerItem16)
        self.btn_get_sn = QtWidgets.QPushButton(self.page_3)
        self.btn_get_sn.setObjectName("btn_get_sn")
        self.horizontalLayout_13.addWidget(self.btn_get_sn)
        spacerItem17 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_13.addItem(spacerItem17)
        self.btn_get_state = QtWidgets.QPushButton(self.page_3)
        self.btn_get_state.setObjectName("btn_get_state")
        self.horizontalLayout_13.addWidget(self.btn_get_state)
        spacerItem18 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_13.addItem(spacerItem18)
        self.verticalLayout_4.addLayout(self.horizontalLayout_13)
        self.stackedWidget.addWidget(self.page_3)
        self.horizontalLayout_3.addWidget(self.stackedWidget)
        self.verticalLayout_5.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.msgWindow = QtWidgets.QTextBrowser(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.msgWindow.sizePolicy().hasHeightForWidth())
        self.msgWindow.setSizePolicy(sizePolicy)
        self.msgWindow.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
        self.msgWindow.setObjectName("msgWindow")
        self.horizontalLayout_4.addWidget(self.msgWindow)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.msg_list = QtWidgets.QListWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.msg_list.sizePolicy().hasHeightForWidth())
        self.msg_list.setSizePolicy(sizePolicy)
        self.msg_list.setStyleSheet("")
        self.msg_list.setLineWidth(0)
        self.msg_list.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.msg_list.setObjectName("msg_list")
        self.verticalLayout_2.addWidget(self.msg_list)
        self.msg_head_list = QtWidgets.QListWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.msg_head_list.sizePolicy().hasHeightForWidth())
        self.msg_head_list.setSizePolicy(sizePolicy)
        self.msg_head_list.setBaseSize(QtCore.QSize(0, 30))
        self.msg_head_list.setStyleSheet("QListWidget::item {\n"
"    height: 30px;\n"
"}\n"
"\n"
"QListWidget{\n"
"        color:green;\n"
"}\n"
"")
        self.msg_head_list.setLineWidth(0)
        self.msg_head_list.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.msg_head_list.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.msg_head_list.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        self.msg_head_list.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
        self.msg_head_list.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.msg_head_list.setMovement(QtWidgets.QListView.Free)
        self.msg_head_list.setResizeMode(QtWidgets.QListView.Adjust)
        self.msg_head_list.setViewMode(QtWidgets.QListView.IconMode)
        self.msg_head_list.setWordWrap(False)
        self.msg_head_list.setItemAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
        self.msg_head_list.setObjectName("msg_head_list")
        self.verticalLayout_2.addWidget(self.msg_head_list)
        self.msg_body_table = QtWidgets.QTableWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.msg_body_table.sizePolicy().hasHeightForWidth())
        self.msg_body_table.setSizePolicy(sizePolicy)
        self.msg_body_table.setStyleSheet("QTableWidget::item{\n"
"    text-align:center;\n"
"}\n"
"QTableWidget::item:hover{\n"
"    background:#FFFFFF;\n"
"}")
        self.msg_body_table.setLineWidth(0)
        self.msg_body_table.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
        self.msg_body_table.setObjectName("msg_body_table")
        self.msg_body_table.setColumnCount(4)
        self.msg_body_table.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        brush = QtGui.QBrush(QtGui.QColor(35, 206, 250))
        brush.setStyle(QtCore.Qt.NoBrush)
        item.setForeground(brush)
        self.msg_body_table.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        brush = QtGui.QBrush(QtGui.QColor(35, 206, 250))
        brush.setStyle(QtCore.Qt.NoBrush)
        item.setForeground(brush)
        self.msg_body_table.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        item.setBackground(QtGui.QColor(35, 206, 250))
        self.msg_body_table.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        item.setBackground(QtGui.QColor(35, 206, 250))
        self.msg_body_table.setHorizontalHeaderItem(3, item)
        self.verticalLayout_2.addWidget(self.msg_body_table)
        self.horizontalLayout_4.addLayout(self.verticalLayout_2)
        self.verticalLayout_5.addLayout(self.horizontalLayout_4)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 593, 25))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.stackedWidget.setCurrentIndex(2)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        __sortingEnabled = self.listWidget.isSortingEnabled()
        self.listWidget.setSortingEnabled(False)
        item = self.listWidget.item(0)
        item.setText(_translate("MainWindow", "连接设备"))
        item = self.listWidget.item(1)
        item.setText(_translate("MainWindow", "设置风泵状态"))
        item = self.listWidget.item(2)
        item.setText(_translate("MainWindow", "读取风泵状态"))
        self.listWidget.setSortingEnabled(__sortingEnabled)
        self.label.setText(_translate("MainWindow", "地址"))
        self.input_server_ip.setText(_translate("MainWindow", "127.0.0.1"))
        self.label_2.setText(_translate("MainWindow", "端口"))
        self.input_server_port.setText(_translate("MainWindow", "30088"))
        self.btn_connect_server.setText(_translate("MainWindow", "连接"))
        self.label_3.setText(_translate("MainWindow", "设备编号"))
        self.label_4.setText(_translate("MainWindow", "设备状态"))
        self.btn_set.setText(_translate("MainWindow", "设置"))
        self.label_6.setText(_translate("MainWindow", "设备编号"))
        self.label_5.setText(_translate("MainWindow", "设备状态"))
        self.btn_get_sn.setText(_translate("MainWindow", "读取编号"))
        self.btn_get_state.setText(_translate("MainWindow", "读取状态"))
        item = self.msg_body_table.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "字段名"))
        item = self.msg_body_table.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "字段码"))
        item = self.msg_body_table.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "字段长"))
        item = self.msg_body_table.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "字段值"))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/939108.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用C#在目录层次结构中搜索文件以查找目标字符串

例程以递归方式搜索目录层次结构中的文件以查找目标字符串。它可以搜索几乎任何类型的文件&#xff0c;即使它不包含 Windows 理解的文本。例如&#xff0c;它可以搜索 DLL 和可执行文件以查看它们是否恰好包含字符串。 下面的代码中显示的ListFiles 方法完成了大部分工作。 …

JAVA爬虫获取1688关键词接口

以下是使用Java爬虫获取1688关键词接口的详细步骤和示例代码&#xff1a; 一、获取API接口访问权限 要使用1688关键词接口&#xff0c;首先需要获取API的使用权限&#xff0c;并了解接口规范。以下是获取API接口的详细步骤&#xff1a; 注册账号&#xff1a;在1688平台注册一…

微服务SpringCloud链路追踪之Micrometer+Zipkin

视频教程&#xff1a; https://www.bilibili.com/video/BV12LBFYjEvR 效果演示 当我们发送一个请求给 Gateway 的时候&#xff0c;由 Micrometer trace 进行链路追踪和数据收集&#xff0c;由 Zipkin 进行数据展示。可以清楚的看到微服务的调用过程&#xff0c;以及每个微服务…

Leetcode 插入区间

class Solution {public int[][] insert(int[][] intervals, int[] newInterval) {List<int[]> result new ArrayList<>();int i 0;// Step 1: 添加所有在 newInterval 之前的区间while(i < intervals.length && intervals[i][1] < newInterval[0]…

CSS|07 标准文档流

标准文档流 一、什么是标准文档流 在制作的 HTML 网页和 PS 画图软件画图时有本质上面的区别: HTML 网页在制作的时候都得遵循一个“流的规则:从左至右、从上至下。 使用 Ps 软件画图时可以在任意地方画图。 <!DOCTYPE html> <html lang"en"> <hea…

redis 缓存使用

工具类 package org.springblade.questionnaire.redis;import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factor…

【排序算法】——选择排序

前言 排序(Sorting) 是计算机程序设计中的一种重要操作&#xff0c;它的功能是将一个数据元素&#xff08;或记录&#xff09;的任意序列&#xff0c;重新排列成一个关键字有序的序列。所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#x…

递归实现指数型枚举(递归)

92. 递归实现指数型枚举 - AcWing题库 每个数有选和不选两种情况 我们把每个数看成每层&#xff0c;可以画出一个递归搜索树 叶子节点就是我们的答案 很容易写出每dfs函数 dfs传入一个u表示层数 当层数大于我们n时&#xff0c;去判断每个数字的选择情况&#xff0c;输出被选…

无限次使用 cursor pro

github地址 cursor-vip 使用方式 在 MacOS/Linux 中&#xff0c;请打开终端&#xff1b; 在 Windows 中&#xff0c;请打开 Git Bash。 然后执行以下命令来安装&#xff1a; 部分电脑可能会误报毒&#xff0c;需要关闭杀毒软件/电脑管家/安全防护再进行 方式1&#xff1a;通过…

【AI热点】小型语言模型(SLM)的崛起:如何在AI时代中找到你的“左膀右臂”?

人工智能模型的演变 多年来&#xff0c;谷歌等科技巨头和OpenAI等初创公司&#xff0c;一直在不遗余力地利用海量在线数据&#xff0c;打造更大、更昂贵的人工智能&#xff08;AI&#xff09;模型。这些大型语言模型&#xff08;LLM&#xff09;被广泛应用于ChatGPT等聊天机器…

解决Nginx + Vue.js (ruoyi-vue) 单页应用(SPA) 404问题的指南

问题描述 在使用Vue.js构建的单页应用&#xff08;SPA&#xff09;中&#xff0c;特别是像ruoyi-vue这样的框架&#xff0c;如果启用了HTML5历史记录模式进行路由管理&#xff0c;那么用户直接访问子路径或刷新页面时可能会遇到404错误。这是因为当用户尝试访问一个非根路径时…

Ubuntu22.04配置3D gaussian splatting

这篇博客提供了3D gaussian splatting在新安装Ubuntu上的配置过程。 1.拉仓库 2.安装显卡驱动和cuda版本 3.安装Pytorch 4.安装Pycharm和配置Python 5.安装附加依赖项&#xff08;方法一&#xff09; 6.安装Anaconda&#xff08;方法二&#xff09; 7.测试 1.拉仓库 # HT…

在 Visual Studio Code 中编译、调试和执行 Makefile 工程 llama2.c

在 Visual Studio Code 中编译、调试和执行 Makefile 工程 llama2.c 1. Installing the extension (在 Visual Studio Code 中安装插件)1.1. Extensions for Visual Studio Code1.2. C/C1.2.1. Pre-requisites 1.3. Makefile Tools 2. Configuring your project (配置项目)2.1.…

深度解析:推荐系统的进化之路与深度学习革命

目录 前深度学习时代一推荐系统的进化之路 浪潮之巅一深度学习在推荐系统中的应用 Embedding 技术在推荐系统中的应用 Embedding的原理 Embedding的分类 Word2vec Item2vec Embedding 与深度学习推荐系统的结合 YouTube 推荐系统召回层 局部敏感哈希 多角度审视推…

MAPTR:在线矢量化高精地图构建的结构化建模与学习(2208)

MAPTR: STRUCTURED MODELING AND LEARNING FOR ONLINE VECTORIZED HD MAP CONSTRUCTION MAPTR&#xff1a;在线矢量化高精地图构建的结构化建模与学习 ABSTRACT High-definition (HD) map provides abundant and precise environmental information of the driving scene, se…

SpringBoot集成Canal实现MySQL实时同步数据到Redis

MySQL增量数据同步利器Canal环境搭建流程 软件环境 JDK17.0.12 canal-server1.1.7 canal-client1.1.7 MySQL5.7 IDEA2024.2.0.2 我们先看Canal1.1.7源码对应的项目结构 1、基于源码编译打包 # 源码下载地址 https://github.com/alibaba/canal # 执行以下命令&#xff0…

嵌入式驱动开发详解16(音频驱动开发)

文章目录 前言WM8960简介I2S协议接口说明 SAI音频接口简介驱动框架简介设备树配置内核使能声卡设置与测试 后续参考文献 前言 该专栏主要是讲解嵌入式相关的驱动开发&#xff0c;但是由于ALSA驱动框架过于复杂&#xff0c;实现音频编解码芯片的驱动不是一个人能完成的&#xf…

OpenGL ES 03 加载3张图片并做混合处理

OpenGL ES 02 加载3张图片并做混合处理 什么是纹理单元纹理单元的作用使用纹理单元的步骤详细解释加载图片并绑定到到GPU纹理单元采样器的设置1.设置采样器变量的纹理单元编号&#xff0c;目的是为了告诉纹理采样器&#xff0c;从哪个纹理单元采集数据2.如果你没有显式地设置采…

JAVA没有搞头了吗?

前言 今年的Java程序员群体似乎承受着前所未有的焦虑。投递简历无人问津&#xff0c;难得的面试机会也难以把握&#xff0c;即便成功入职&#xff0c;也往往难以长久。于是&#xff0c;不少程序员感叹&#xff1a;互联网的寒冬似乎又一次卷土重来&#xff0c;环境如此恶劣&…

短视频矩阵贴牌:打造品牌新势力的策略与实践

在数字化浪潮席卷全球的今天&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为连接用户与品牌的重要桥梁。企业为了快速抢占市场&#xff0c;提升品牌影响力&#xff0c;纷纷探索短视频矩阵贴牌这一新兴模式。本文将深入探讨短视频矩阵贴牌的概念、优势、实施流程及注…