pyqtgraph 多线程 绘图

在开源代码基础上修改
https://github.com/ixjlyons/embed-pyqtgraph-tutorial

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtWidgets, QtGui, QtCore
from ctypes import *
import pyqtgraph as pg
import sys
import os
import random
import time
import socket
import struct
import array
import threading
import stop_thread
import xlwt
import xlwt
import xlrd

# import the "form class" from your compiled UI
from template import Ui_CustomWidget

class CustomWidget(QtGui.QWidget):
    udp_recv_signal = pyqtSignal(bytes)

    def __init__(self, parent=None):
        super(CustomWidget, self).__init__(parent=parent)

        # set up the form class as a `ui` attribute
        self.ui = Ui_CustomWidget()
        self.ui.setupUi(self)

        self.time_begin = 0

        self.socket_fd = 0
        self.udp_recv_thread = threading.Thread(target=self.udp_recv_packet)

        self.ui.plotWidget.addLegend()
        self.ui.plotWidget.setLimits(xMin=0, yMin=0)
        # self.ui.plotWidget.setXRange(0, 50, padding=0)
        # self.ui.plotWidget.setYRange(0, 20000, padding=0)
        self.ui.plotWidget.setLabel('left', "Value")
        self.ui.plotWidget.setLabel('bottom', "Times", units='s')
        self.ui.plotWidget.showGrid(x=True, y=True)
        # self.ui.plotWidget.setMouseEnabled(x=enabled, y=enabled)
        self.vb = self.ui.plotWidget.plotItem.vb

        # cross hair
        self.vLine = pg.InfiniteLine(angle=90, movable=False)
        # self.hLine = pg.InfiniteLine(angle=0, movable=False)
        self.ui.plotWidget.addItem(self.vLine, ignoreBounds=True)
        # self.ui.plotWidget.addItem(self.hLine, ignoreBounds=True)

        self.setLcdStyle(self.ui.VbuslcdNumber)
        self.setLcdStyle(self.ui.IbuslcdNumber)
        self.setLcdStyle(self.ui.VcpinlcdNumber)
        self.setLcdStyle(self.ui.IcpinlcdNumber)
        self.setLcdStyle(self.ui.VbatlcdNumber)
        self.setLcdStyle(self.ui.IbatlcdNumber)
        self.setLcdStyle(self.ui.TbatlcdNumber)
        self.setLcdStyle(self.ui.TimelcdNumber)

        #create curves
        self.vbus_curve = self.ui.plotWidget.plot(pen=(100,30,22), name="Vbus(mV)")
        self.ibus_curve = self.ui.plotWidget.plot(pen=(14,98,81), name="Ibus(mA)")
        self.vcpin_curve = self.ui.plotWidget.plot(pen=(231,76,60), name="Vcpin(mV)")
        self.icpin_curve = self.ui.plotWidget.plot(pen=(88,214,141), name="Icpin(mA)")
        self.vbat_curve = self.ui.plotWidget.plot(pen=(245,183,177), name="Vbat(mV)")
        self.ibat_curve = self.ui.plotWidget.plot(pen=(171,235,198), name="Ibat(mA)")
        self.tbat_curve = self.ui.plotWidget.plot(pen=(211,84,0), name="Tbat(℃ 100X)")

        #create array list
        self.time_list = array.array('l')
        self.vbus_list = array.array('l')
        self.ibus_list = array.array('l')
        self.vcpin_list = array.array('l')
        self.icpin_list = array.array('l')
        self.vbat_list = array.array('l')
        self.ibat_list = array.array('l')
        self.tbat_list = array.array('l')
       
        # simple demonstration of pure Qt widgets interacting with pyqtgraph
        self.ui.DisplaycheckBox.stateChanged.connect(self.toggleMouse)
        self.udp_recv_signal.connect(self.udp_packet_handle)
        self.ui.StartpushButton.clicked.connect(lambda: self.buttonStatusChanged(self.ui.StartpushButton))
        self.ui.StoppushButton.clicked.connect(lambda: self.buttonStatusChanged(self.ui.StoppushButton))
        self.ui.SavepushButton.clicked.connect(lambda: self.buttonStatusChanged(self.ui.SavepushButton))
        self.ui.RestoreushButton.clicked.connect(lambda: self.buttonStatusChanged(self.ui.RestoreushButton))
        self.ui.numscomboBox.currentIndexChanged.connect(self.numscomboBoxChangedHandler)
        # self.ui.plotWidget.scene().sigMouseMoved.connect(self.mouseMoved)
        self.proxy = pg.SignalProxy(self.ui.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)

        self.stacking_enbale = True

        self.is_running = False

    def udp_packet_handle(self, data):
        # print('msg_type', data[0], 'msg_len', data[1])
        if data[0] == 0: #data report
            msg_type, msg_len,  vbus, ibus, vcp, icp, vbat, ibat, tbat = struct.unpack('!2B7i', data)
            print(vbus, ibus, vcp, icp, vbat, ibat, tbat)
            if len(self.time_list) == 0:
                self.time_begin = time.time()
                self.time_list.append(0)
            else:
                self.time_list.append(time.time() - self.time_begin)
            self.vbus_list.append(vbus)
            self.ibus_list.append(ibus)
            self.vcpin_list.append(vcp)
            self.icpin_list.append(icp)
            self.vbat_list.append(vbat)
            self.ibat_list.append(ibat)
            self.tbat_list.append(tbat * 10)

            if self.stacking_enbale == False and len(self.vbus_list) > 50:
                self.vbus_curve.setData(self.time_list[-50:], self.vbus_list[-50:])
                self.ibus_curve.setData(self.time_list[-50:], self.ibus_list[-50:])
                self.vcpin_curve.setData(self.time_list[-50:], self.vcpin_list[-50:])
                self.icpin_curve.setData(self.time_list[-50:], self.icpin_list[-50:])
                self.vbat_curve.setData(self.time_list[-50:], self.vbat_list[-50:])
                self.ibat_curve.setData(self.time_list[-50:], self.ibat_list[-50:])
                self.tbat_curve.setData(self.time_list[-50:], self.tbat_list[-50:])
            else:
                self.vbus_curve.setData(self.time_list, self.vbus_list)
                self.ibus_curve.setData(self.time_list, self.ibus_list)
                self.vcpin_curve.setData(self.time_list, self.vcpin_list)
                self.icpin_curve.setData(self.time_list, self.icpin_list)
                self.vbat_curve.setData(self.time_list, self.vbat_list)
                self.ibat_curve.setData(self.time_list, self.ibat_list)
                self.tbat_curve.setData(self.time_list, self.tbat_list)

            if self.ui.numscomboBox.currentText() == '显示最大数据':
                self.ui.VbuslcdNumber.display(max(self.vbus_list))
                self.ui.IbuslcdNumber.display(max(self.ibus_list))
                self.ui.VcpinlcdNumber.display(max(self.vcpin_list))
                self.ui.IcpinlcdNumber.display(max(self.icpin_list))
                self.ui.VbatlcdNumber.display(max(self.vbat_list))
                self.ui.IbatlcdNumber.display(max(self.ibat_list))
                self.ui.TbatlcdNumber.display(max(self.tbat_list))
                self.ui.TimelcdNumber.display(int(self.time_list[-1]))
            elif self.ui.numscomboBox.currentText() == '显示最新数据':
                self.ui.VbuslcdNumber.display(self.vbus_list[-1])
                self.ui.IbuslcdNumber.display(self.ibus_list[-1])
                self.ui.VcpinlcdNumber.display(self.vcpin_list[-1])
                self.ui.IcpinlcdNumber.display(self.icpin_list[-1])
                self.ui.VbatlcdNumber.display(self.vbat_list[-1])
                self.ui.IbatlcdNumber.display(self.ibat_list[-1])
                self.ui.TbatlcdNumber.display(self.tbat_list[-1])
                self.ui.TimelcdNumber.display(int(self.time_list[-1]))
        elif data[0] == 1:
            pass
        else:
            pass

    def toggleMouse(self, state):
        if state == QtCore.Qt.Checked:
            self.stacking_enbale = True
        else:
            self.stacking_enbale = False

    def mouseMoved(self, evt):

        if self.ui.numscomboBox.currentText() != '显示游标数据':
            return

        pos = evt[0]  ## using signal proxy turns original arguments into a tuple
        if self.ui.plotWidget.sceneBoundingRect().contains(pos):
            mousePoint = self.vb.mapSceneToView(pos)
            index = 0

            for i in self.time_list:
                # print("debug:", index, i, mousePoint.x(), self.time_list)
                if i >= mousePoint.x():
                    if index != 0:
                        index = index - 1
                    break
                else:
                    index = index + 1

            if index < 0 or index >= len(self.time_list):
                return

            self.ui.VbuslcdNumber.display(self.vbus_list[index])
            self.ui.IbuslcdNumber.display(self.ibus_list[index])
            self.ui.VcpinlcdNumber.display(self.vcpin_list[index])
            self.ui.IcpinlcdNumber.display(self.icpin_list[index])
            self.ui.VbatlcdNumber.display(self.vbat_list[index])
            self.ui.IbatlcdNumber.display(self.ibat_list[index])
            self.ui.TbatlcdNumber.display(self.tbat_list[index])
            self.ui.TimelcdNumber.display(int(self.time_list[index]))

            self.vLine.setPos(mousePoint.x())
            # self.hLine.setPos(mousePoint.y())

    def buttonStatusChanged(self, btn):
        if btn.text() == '开始':
            self.ui.StartpushButton.setEnabled(False)
            self.ui.StoppushButton.setEnabled(True)
            self.ui.SavepushButton.setEnabled(False)
            self.ui.RestoreushButton.setEnabled(False)
            self.ui.RestoreushButton.setEnabled(False)
            self.ui.IplineEdit.setEnabled(False)
            self.ui.PortlineEdit.setEnabled(False)
            self.ui.IntervallineEdit.setEnabled(False)

            # clear previous curve and data
            self.curve_display_clear()

            # init udp socket
            self.udp_client_init()

            # send local socket info to peer
            self.udp_send(self.send_init_msg)

            # start udp thread
            self.udp_recv_thread.start()
            self.is_running = True
        elif btn.text() == '停止':
            self.stopEventHandle()
        elif btn.text() == '保存':
            self.ui.SavepushButton.setEnabled(False)
            if len(self.time_list) != 0:
                self.save_data_to_file(os.getcwd())
            self.ui.SavepushButton.setEnabled(True)
        elif btn.text() == '回放':
            self.ui.RestoreushButton.setEnabled(False)
            self.curve_display_clear()
            openfile_name = QFileDialog.getOpenFileName(self, '选择文件', '')
            if openfile_name[0] != '':
                self.read_data_from_file(openfile_name)
            self.ui.RestoreushButton.setEnabled(True)

    def stopEventHandle(self):
        if self.is_running == False:
            return

        self.is_running = False
        self.time_begin = 0
        self.udp_close()
        self.ui.StartpushButton.setEnabled(True)
        self.ui.StoppushButton.setEnabled(False)

        if len(self.time_list) != 0:
            self.ui.SavepushButton.setEnabled(True)

        self.ui.RestoreushButton.setEnabled(True)
        self.ui.IplineEdit.setEnabled(True)
        self.ui.PortlineEdit.setEnabled(True)
        self.ui.IntervallineEdit.setEnabled(True)

        # stop udp thread
        stop_thread.stop_thread(self.udp_recv_thread)
        # self.udp_recv_thread.join()

    def numscomboBoxChangedHandler(self, i):
        if self.ui.numscomboBox.currentText() == '显示最大数据':
            self.vLine.setEnabled(False)
            self.vLine.setPos(0)
        elif self.ui.numscomboBox.currentText() == '显示最新数据':
            self.vLine.setEnabled(False)
            self.vLine.setPos(0)
        elif self.ui.numscomboBox.currentText() != '显示游标数据':
            self.vLine.setEnabled(True)

    def curve_display_clear(self):
        self.time_list = []
        self.vbus_list = []
        self.ibus_list = []
        self.vcpin_list = []
        self.icpin_list = []
        self.vbat_list = []
        self.ibat_list = []
        self.tbat_list = []
        self.vbus_curve.setData(self.vbus_list)
        self.ibus_curve.setData(self.ibus_list)
        self.vcpin_curve.setData(self.vcpin_list)
        self.icpin_curve.setData(self.icpin_list)
        self.vbat_curve.setData(self.vbat_list)
        self.ibat_curve.setData(self.ibat_list)
        self.tbat_curve.setData(self.tbat_list)

    def udp_client_init(self):
        """
        确认UDP客户端的ip及地址
        :return:
        """
        self.socket_fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.address = None
        self.send_init_msg = struct.pack('!2B', 1, 0)

    def udp_recv_packet(self):
        """
        用于创建一个线程持续监听UDP通信
        :return:
        """
        print('udp recv loop into')
        while self.is_running == True:
            print('udp peer socket info:', self.socket_fd.getsockname())
            data, addr = self.socket_fd.recvfrom(1024)
            print(addr, "\t", data)
            self.udp_recv_signal.emit(data)
        print('udp recv loop exit')

    def udp_send(self, udp_msg):
        """
        功能函数,用于UDP客户端发送消息
        :return: None
        """
        if self.socket_fd:
            self.address = (str(self.ui.IplineEdit.text()), int(self.ui.PortlineEdit.text()))
            print(str(self.ui.IplineEdit.text()), int(self.ui.PortlineEdit.text()))
            self.socket_fd.sendto(udp_msg, self.address)

    def udp_close(self):
        """
        功能函数,关闭网络连接的方法
        :return:
        """
        if self.socket_fd:
            self.socket_fd.close()

    def read_data_from_file(self, file_path):
        print('openfile_name', file_path)
        read_book = xlrd.open_workbook(file_path[0])
        read_sheets = read_book.sheet_names()
        print('read_sheets', read_sheets)
        read_table = read_book.sheet_by_name(read_sheets[0])
        rowNum = read_table.nrows
        colNum = read_table.ncols
        print('rowNum', rowNum, 'colNum', colNum)

        if colNum != 8:
            print('sheet format error, colNum: ', colNum)
            return

        for i in range(rowNum - 1):
            self.time_list.append(read_table.cell_value(i + 1, 0))
            self.vbus_list.append(read_table.cell_value(i + 1, 1))
            self.ibus_list.append(read_table.cell_value(i + 1, 2))
            self.vcpin_list.append(read_table.cell_value(i + 1, 3))
            self.icpin_list.append(read_table.cell_value(i + 1, 4))
            self.vbat_list.append(read_table.cell_value(i + 1, 5))
            self.ibat_list.append(read_table.cell_value(i + 1, 6))
            self.tbat_list.append(read_table.cell_value(i + 1, 7))

        self.vbus_curve.setData(self.time_list, self.vbus_list)
        self.ibus_curve.setData(self.time_list, self.ibus_list)
        self.vcpin_curve.setData(self.time_list, self.vcpin_list)
        self.icpin_curve.setData(self.time_list, self.icpin_list)
        self.vbat_curve.setData(self.time_list, self.vbat_list)
        self.ibat_curve.setData(self.time_list, self.ibat_list)
        self.tbat_curve.setData(self.time_list, self.tbat_list)


    def save_data_to_file(self, file_path):
        file_name = time.strftime("SQC-%Y-%m-%d-%H-%M-%S.xlsx", time.localtime())

        f = xlwt.Workbook()
        sheet1 = f.add_sheet(u'sqc测试数据', cell_overwrite_ok=True)  # 创建sheet
        # 将数据写入第 i 行,第 j 列
        sheet1.write(0, 0, '时间(s)')
        sheet1.write(0, 1, 'Vbus(mV)')
        sheet1.write(0, 2, 'Ibus(mA)')
        sheet1.write(0, 3, 'Vcp(mV)')
        sheet1.write(0, 4, 'Icp(mA)')
        sheet1.write(0, 5, 'Vbat(mV)')
        sheet1.write(0, 6, 'Ibat(mA)')
        sheet1.write(0, 7, 'Tbat(℃)')

        # save data list
        for i in range(len(self.time_list)):
            sheet1.write(i + 1, 0, self.time_list[i])
            sheet1.write(i + 1, 1, self.vbus_list[i])
            sheet1.write(i + 1, 2, self.ibus_list[i])
            sheet1.write(i + 1, 3, self.vcpin_list[i])
            sheet1.write(i + 1, 4, self.icpin_list[i])
            sheet1.write(i + 1, 5, self.vbat_list[i])
            sheet1.write(i + 1, 6, self.ibat_list[i])
            sheet1.write(i + 1, 7, self.tbat_list[i])

        print('Save path: ', file_path + '/' +file_name)

        f.save(file_path + '/' + file_name) # 保存文件

    def setLcdStyle(self,  lcddisplay):
        lcddisplay.setDigitCount(5)
        lcddisplay.setSegmentStyle(QLCDNumber.Flat)
        lcdpat = lcddisplay.palette()
        lcdpat.setColor(QPalette.Normal, QPalette.WindowText, Qt.red)
        lcddisplay.setPalette(lcdpat)

    # 添加中文的确认退出提示框1
    def closeEvent(self, event):
        # 创建一个消息盒子(提示框)
        quitMsgBox = QMessageBox()
        # 设置提示框的标题
        quitMsgBox.setWindowTitle('确认提示')
        # 设置提示框的内容
        quitMsgBox.setText('你确认退出吗?')
        # 设置按钮标准,一个yes一个no
        quitMsgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        # 获取两个按钮并且修改显示文本
        buttonY = quitMsgBox.button(QMessageBox.Yes)
        buttonY.setText('确定')
        buttonN = quitMsgBox.button(QMessageBox.No)
        buttonN.setText('取消')
        quitMsgBox.exec_()
        # 判断返回值,如果点击的是Yes按钮,我们就关闭组件和应用,否则就忽略关闭事件
        if quitMsgBox.clickedButton() == buttonY:
            self.stopEventHandle()
            event.accept()
        else:
            event.ignore()

if __name__ == '__main__':
    app = QtGui.QApplication([])
    widget = CustomWidget()
    widget.show()
    app.exec_()


<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>CustomWidget</class>
 <widget class="QWidget" name="CustomWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1101</width>
    <height>593</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_9">
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_6">
     <item>
      <widget class="PlotWidget" name="plotWidget"/>
     </item>
     <item>
      <widget class="Line" name="line_2">
       <property name="orientation">
        <enum>Qt::Vertical</enum>
       </property>
      </widget>
     </item>
     <item>
      <layout class="QVBoxLayout" name="verticalLayout_8">
       <item>
        <widget class="Line" name="line_30">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
        </widget>
       </item>
       <item>
        <layout class="QGridLayout" name="gridLayout_2">
         <item row="6" column="0">
          <layout class="QHBoxLayout" name="horizontalLayout_12">
           <item>
            <widget class="Line" name="line_25">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLabel" name="label_11">
             <property name="text">
              <string>TBAT:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="TbatlcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="0" column="0">
          <layout class="QHBoxLayout" name="horizontalLayout_8">
           <item>
            <widget class="Line" name="line_22">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLabel" name="label_7">
             <property name="text">
              <string>VBUS:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="VbuslcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="4" column="2">
          <layout class="QHBoxLayout" name="horizontalLayout_13">
           <item>
            <widget class="QLabel" name="label_12">
             <property name="text">
              <string>IBAT:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="IbatlcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="4" column="0">
          <layout class="QHBoxLayout" name="horizontalLayout_14">
           <item>
            <widget class="Line" name="line_24">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLabel" name="label_13">
             <property name="text">
              <string>VBAT:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="VbatlcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="2" column="2">
          <layout class="QHBoxLayout" name="horizontalLayout_11">
           <item>
            <widget class="QLabel" name="label_10">
             <property name="text">
              <string>ICPin:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="IcpinlcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="2" column="0">
          <layout class="QHBoxLayout" name="horizontalLayout_10">
           <item>
            <widget class="Line" name="line_23">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLabel" name="label_9">
             <property name="text">
              <string>VCPin:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="VcpinlcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="0" column="2">
          <layout class="QHBoxLayout" name="horizontalLayout_9">
           <item>
            <widget class="QLabel" name="label_8">
             <property name="text">
              <string>IBUS:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="IbuslcdNumber"/>
           </item>
          </layout>
         </item>
         <item row="5" column="0">
          <widget class="Line" name="line_14">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="1" column="1">
          <widget class="Line" name="line_17">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="0" column="1">
          <widget class="Line" name="line_19">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="3" column="1">
          <widget class="Line" name="line_18">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="1" column="0">
          <widget class="Line" name="line_16">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="2" column="1">
          <widget class="Line" name="line_13">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="3" column="0">
          <widget class="Line" name="line_15">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="6" column="1">
          <widget class="Line" name="line_21">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="4" column="1">
          <widget class="Line" name="line_20">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="0" column="3">
          <widget class="Line" name="line_26">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="2" column="3">
          <widget class="Line" name="line_27">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="4" column="3">
          <widget class="Line" name="line_28">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="6" column="3">
          <widget class="Line" name="line_29">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item row="5" column="2">
          <widget class="Line" name="line_31">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="3" column="2">
          <widget class="Line" name="line_32">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="1" column="2">
          <widget class="Line" name="line_33">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="5" column="1">
          <widget class="Line" name="line_34">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item row="6" column="2">
          <layout class="QHBoxLayout" name="horizontalLayout_15">
           <item>
            <widget class="QLabel" name="label_14">
             <property name="text">
              <string>TIME:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLCDNumber" name="TimelcdNumber"/>
           </item>
          </layout>
         </item>
        </layout>
       </item>
       <item>
        <widget class="Line" name="line_10">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
        </widget>
       </item>
       <item>
        <spacer name="verticalSpacer">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>248</width>
           <height>323</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
    </layout>
   </item>
   <item>
    <layout class="QVBoxLayout" name="verticalLayout_7">
     <item>
      <widget class="Line" name="line_9">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
      </widget>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_16">
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout_3">
         <item>
          <widget class="Line" name="line">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
         <item>
          <widget class="Line" name="line_12">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout_2">
           <item>
            <widget class="QLabel" name="label_2">
             <property name="text">
              <string>  显示方式</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QCheckBox" name="DisplaycheckBox">
             <property name="enabled">
              <bool>true</bool>
             </property>
             <property name="text">
              <string>堆积/滚动</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_3">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout_3">
           <item>
            <widget class="QLabel" name="label_3">
             <property name="text">
              <string> LOG开关</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QCheckBox" name="LogcheckBox">
             <property name="enabled">
              <bool>true</bool>
             </property>
             <property name="text">
              <string>ON/OFF</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_4">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout_4">
           <item>
            <widget class="QLabel" name="label_4">
             <property name="text">
              <string>  DUMPER</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QCheckBox" name="DumpcheckBox">
             <property name="enabled">
              <bool>true</bool>
             </property>
             <property name="text">
              <string>ON/OFF</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_5">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout_5">
           <item>
            <widget class="QLabel" name="label_5">
             <property name="text">
              <string>  待定</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QCheckBox" name="checkBox_4">
             <property name="enabled">
              <bool>true</bool>
             </property>
             <property name="text">
              <string>ON/OFF</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_6">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
        </layout>
       </item>
       <item>
        <spacer name="horizontalSpacer">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>48</width>
           <height>51</height>
          </size>
         </property>
        </spacer>
       </item>
       <item>
        <widget class="Line" name="line_11">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
        </widget>
       </item>
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout_7">
         <item>
          <layout class="QVBoxLayout" name="verticalLayout_6">
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_5">
             <item>
              <widget class="QLabel" name="label_6">
               <property name="text">
                <string>数据显示方式:</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QComboBox" name="numscomboBox">
               <item>
                <property name="text">
                 <string>显示最新数据</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>显示最大数据</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>显示游标数据</string>
                </property>
               </item>
              </widget>
             </item>
            </layout>
           </item>
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_4">
             <item>
              <widget class="QLabel" name="Iplabel_2">
               <property name="text">
                <string>采集间隔(ms):</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QLineEdit" name="IntervallineEdit">
               <property name="text">
                <string>1000</string>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_7">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout">
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout">
             <item>
              <widget class="QLabel" name="Iplabel">
               <property name="text">
                <string>IP地址:</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QLineEdit" name="IplineEdit">
               <property name="text">
                <string>192.168.1.111</string>
               </property>
               <property name="maxLength">
                <number>15</number>
               </property>
              </widget>
             </item>
            </layout>
           </item>
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_2">
             <item>
              <widget class="QLabel" name="Portlabel">
               <property name="text">
                <string>  端口:</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QLineEdit" name="PortlineEdit">
               <property name="text">
                <string>8106</string>
               </property>
               <property name="maxLength">
                <number>5</number>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_8">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
         <item>
          <layout class="QGridLayout" name="gridLayout">
           <item row="0" column="0">
            <widget class="QPushButton" name="StartpushButton">
             <property name="text">
              <string>开始</string>
             </property>
            </widget>
           </item>
           <item row="0" column="1">
            <widget class="QPushButton" name="StoppushButton">
             <property name="enabled">
              <bool>false</bool>
             </property>
             <property name="text">
              <string>停止</string>
             </property>
            </widget>
           </item>
           <item row="1" column="1">
            <widget class="QPushButton" name="RestoreushButton">
             <property name="text">
              <string>回放</string>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QPushButton" name="SavepushButton">
             <property name="enabled">
              <bool>false</bool>
             </property>
             <property name="text">
              <string>保存</string>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="Line" name="line_35">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
        </layout>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>PlotWidget</class>
   <extends>QGraphicsView</extends>
   <header>pyqtgraph</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

import ctypes
import inspect


# 强制关闭线程的方法
def _async_raise(tid, exc_type):
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exc_type):
        exc_type = type(exc_type)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exc_type))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")


def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)


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

# Form implementation generated from reading ui file 'template.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_CustomWidget(object):
    def setupUi(self, CustomWidget):
        CustomWidget.setObjectName("CustomWidget")
        CustomWidget.resize(1101, 593)
        self.verticalLayout_9 = QtWidgets.QVBoxLayout(CustomWidget)
        self.verticalLayout_9.setObjectName("verticalLayout_9")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.plotWidget = PlotWidget(CustomWidget)
        self.plotWidget.setObjectName("plotWidget")
        self.horizontalLayout_6.addWidget(self.plotWidget)
        self.line_2 = QtWidgets.QFrame(CustomWidget)
        self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.horizontalLayout_6.addWidget(self.line_2)
        self.verticalLayout_8 = QtWidgets.QVBoxLayout()
        self.verticalLayout_8.setObjectName("verticalLayout_8")
        self.line_30 = QtWidgets.QFrame(CustomWidget)
        self.line_30.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_30.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_30.setObjectName("line_30")
        self.verticalLayout_8.addWidget(self.line_30)
        self.gridLayout_2 = QtWidgets.QGridLayout()
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        self.line_25 = QtWidgets.QFrame(CustomWidget)
        self.line_25.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_25.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_25.setObjectName("line_25")
        self.horizontalLayout_12.addWidget(self.line_25)
        self.label_11 = QtWidgets.QLabel(CustomWidget)
        self.label_11.setObjectName("label_11")
        self.horizontalLayout_12.addWidget(self.label_11)
        self.TbatlcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.TbatlcdNumber.setObjectName("TbatlcdNumber")
        self.horizontalLayout_12.addWidget(self.TbatlcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_12, 6, 0, 1, 1)
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        self.line_22 = QtWidgets.QFrame(CustomWidget)
        self.line_22.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_22.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_22.setObjectName("line_22")
        self.horizontalLayout_8.addWidget(self.line_22)
        self.label_7 = QtWidgets.QLabel(CustomWidget)
        self.label_7.setObjectName("label_7")
        self.horizontalLayout_8.addWidget(self.label_7)
        self.VbuslcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.VbuslcdNumber.setObjectName("VbuslcdNumber")
        self.horizontalLayout_8.addWidget(self.VbuslcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_8, 0, 0, 1, 1)
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
        self.label_12 = QtWidgets.QLabel(CustomWidget)
        self.label_12.setObjectName("label_12")
        self.horizontalLayout_13.addWidget(self.label_12)
        self.IbatlcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.IbatlcdNumber.setObjectName("IbatlcdNumber")
        self.horizontalLayout_13.addWidget(self.IbatlcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_13, 4, 2, 1, 1)
        self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
        self.line_24 = QtWidgets.QFrame(CustomWidget)
        self.line_24.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_24.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_24.setObjectName("line_24")
        self.horizontalLayout_14.addWidget(self.line_24)
        self.label_13 = QtWidgets.QLabel(CustomWidget)
        self.label_13.setObjectName("label_13")
        self.horizontalLayout_14.addWidget(self.label_13)
        self.VbatlcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.VbatlcdNumber.setObjectName("VbatlcdNumber")
        self.horizontalLayout_14.addWidget(self.VbatlcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_14, 4, 0, 1, 1)
        self.horizontalLayout_11 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
        self.label_10 = QtWidgets.QLabel(CustomWidget)
        self.label_10.setObjectName("label_10")
        self.horizontalLayout_11.addWidget(self.label_10)
        self.IcpinlcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.IcpinlcdNumber.setObjectName("IcpinlcdNumber")
        self.horizontalLayout_11.addWidget(self.IcpinlcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_11, 2, 2, 1, 1)
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
        self.line_23 = QtWidgets.QFrame(CustomWidget)
        self.line_23.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_23.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_23.setObjectName("line_23")
        self.horizontalLayout_10.addWidget(self.line_23)
        self.label_9 = QtWidgets.QLabel(CustomWidget)
        self.label_9.setObjectName("label_9")
        self.horizontalLayout_10.addWidget(self.label_9)
        self.VcpinlcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.VcpinlcdNumber.setObjectName("VcpinlcdNumber")
        self.horizontalLayout_10.addWidget(self.VcpinlcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_10, 2, 0, 1, 1)
        self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
        self.label_8 = QtWidgets.QLabel(CustomWidget)
        self.label_8.setObjectName("label_8")
        self.horizontalLayout_9.addWidget(self.label_8)
        self.IbuslcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.IbuslcdNumber.setObjectName("IbuslcdNumber")
        self.horizontalLayout_9.addWidget(self.IbuslcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_9, 0, 2, 1, 1)
        self.line_14 = QtWidgets.QFrame(CustomWidget)
        self.line_14.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_14.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_14.setObjectName("line_14")
        self.gridLayout_2.addWidget(self.line_14, 5, 0, 1, 1)
        self.line_17 = QtWidgets.QFrame(CustomWidget)
        self.line_17.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_17.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_17.setObjectName("line_17")
        self.gridLayout_2.addWidget(self.line_17, 1, 1, 1, 1)
        self.line_19 = QtWidgets.QFrame(CustomWidget)
        self.line_19.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_19.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_19.setObjectName("line_19")
        self.gridLayout_2.addWidget(self.line_19, 0, 1, 1, 1)
        self.line_18 = QtWidgets.QFrame(CustomWidget)
        self.line_18.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_18.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_18.setObjectName("line_18")
        self.gridLayout_2.addWidget(self.line_18, 3, 1, 1, 1)
        self.line_16 = QtWidgets.QFrame(CustomWidget)
        self.line_16.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_16.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_16.setObjectName("line_16")
        self.gridLayout_2.addWidget(self.line_16, 1, 0, 1, 1)
        self.line_13 = QtWidgets.QFrame(CustomWidget)
        self.line_13.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_13.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_13.setObjectName("line_13")
        self.gridLayout_2.addWidget(self.line_13, 2, 1, 1, 1)
        self.line_15 = QtWidgets.QFrame(CustomWidget)
        self.line_15.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_15.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_15.setObjectName("line_15")
        self.gridLayout_2.addWidget(self.line_15, 3, 0, 1, 1)
        self.line_21 = QtWidgets.QFrame(CustomWidget)
        self.line_21.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_21.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_21.setObjectName("line_21")
        self.gridLayout_2.addWidget(self.line_21, 6, 1, 1, 1)
        self.line_20 = QtWidgets.QFrame(CustomWidget)
        self.line_20.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_20.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_20.setObjectName("line_20")
        self.gridLayout_2.addWidget(self.line_20, 4, 1, 1, 1)
        self.line_26 = QtWidgets.QFrame(CustomWidget)
        self.line_26.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_26.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_26.setObjectName("line_26")
        self.gridLayout_2.addWidget(self.line_26, 0, 3, 1, 1)
        self.line_27 = QtWidgets.QFrame(CustomWidget)
        self.line_27.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_27.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_27.setObjectName("line_27")
        self.gridLayout_2.addWidget(self.line_27, 2, 3, 1, 1)
        self.line_28 = QtWidgets.QFrame(CustomWidget)
        self.line_28.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_28.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_28.setObjectName("line_28")
        self.gridLayout_2.addWidget(self.line_28, 4, 3, 1, 1)
        self.line_29 = QtWidgets.QFrame(CustomWidget)
        self.line_29.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_29.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_29.setObjectName("line_29")
        self.gridLayout_2.addWidget(self.line_29, 6, 3, 1, 1)
        self.line_31 = QtWidgets.QFrame(CustomWidget)
        self.line_31.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_31.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_31.setObjectName("line_31")
        self.gridLayout_2.addWidget(self.line_31, 5, 2, 1, 1)
        self.line_32 = QtWidgets.QFrame(CustomWidget)
        self.line_32.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_32.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_32.setObjectName("line_32")
        self.gridLayout_2.addWidget(self.line_32, 3, 2, 1, 1)
        self.line_33 = QtWidgets.QFrame(CustomWidget)
        self.line_33.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_33.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_33.setObjectName("line_33")
        self.gridLayout_2.addWidget(self.line_33, 1, 2, 1, 1)
        self.line_34 = QtWidgets.QFrame(CustomWidget)
        self.line_34.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_34.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_34.setObjectName("line_34")
        self.gridLayout_2.addWidget(self.line_34, 5, 1, 1, 1)
        self.horizontalLayout_15 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_15.setObjectName("horizontalLayout_15")
        self.label_14 = QtWidgets.QLabel(CustomWidget)
        self.label_14.setObjectName("label_14")
        self.horizontalLayout_15.addWidget(self.label_14)
        self.TimelcdNumber = QtWidgets.QLCDNumber(CustomWidget)
        self.TimelcdNumber.setObjectName("TimelcdNumber")
        self.horizontalLayout_15.addWidget(self.TimelcdNumber)
        self.gridLayout_2.addLayout(self.horizontalLayout_15, 6, 2, 1, 1)
        self.verticalLayout_8.addLayout(self.gridLayout_2)
        self.line_10 = QtWidgets.QFrame(CustomWidget)
        self.line_10.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_10.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_10.setObjectName("line_10")
        self.verticalLayout_8.addWidget(self.line_10)
        spacerItem = QtWidgets.QSpacerItem(248, 323, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_8.addItem(spacerItem)
        self.horizontalLayout_6.addLayout(self.verticalLayout_8)
        self.verticalLayout_9.addLayout(self.horizontalLayout_6)
        self.verticalLayout_7 = QtWidgets.QVBoxLayout()
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.line_9 = QtWidgets.QFrame(CustomWidget)
        self.line_9.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_9.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_9.setObjectName("line_9")
        self.verticalLayout_7.addWidget(self.line_9)
        self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_16.setObjectName("horizontalLayout_16")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.line = QtWidgets.QFrame(CustomWidget)
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.horizontalLayout_3.addWidget(self.line)
        self.line_12 = QtWidgets.QFrame(CustomWidget)
        self.line_12.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_12.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_12.setObjectName("line_12")
        self.horizontalLayout_3.addWidget(self.line_12)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label_2 = QtWidgets.QLabel(CustomWidget)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_2.addWidget(self.label_2)
        self.DisplaycheckBox = QtWidgets.QCheckBox(CustomWidget)
        self.DisplaycheckBox.setEnabled(True)
        self.DisplaycheckBox.setChecked(True)
        self.DisplaycheckBox.setObjectName("DisplaycheckBox")
        self.verticalLayout_2.addWidget(self.DisplaycheckBox)
        self.horizontalLayout_3.addLayout(self.verticalLayout_2)
        self.line_3 = QtWidgets.QFrame(CustomWidget)
        self.line_3.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_3.setObjectName("line_3")
        self.horizontalLayout_3.addWidget(self.line_3)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.label_3 = QtWidgets.QLabel(CustomWidget)
        self.label_3.setObjectName("label_3")
        self.verticalLayout_3.addWidget(self.label_3)
        self.LogcheckBox = QtWidgets.QCheckBox(CustomWidget)
        self.LogcheckBox.setEnabled(True)
        self.LogcheckBox.setChecked(True)
        self.LogcheckBox.setObjectName("LogcheckBox")
        self.verticalLayout_3.addWidget(self.LogcheckBox)
        self.horizontalLayout_3.addLayout(self.verticalLayout_3)
        self.line_4 = QtWidgets.QFrame(CustomWidget)
        self.line_4.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_4.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_4.setObjectName("line_4")
        self.horizontalLayout_3.addWidget(self.line_4)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.label_4 = QtWidgets.QLabel(CustomWidget)
        self.label_4.setObjectName("label_4")
        self.verticalLayout_4.addWidget(self.label_4)
        self.DumpcheckBox = QtWidgets.QCheckBox(CustomWidget)
        self.DumpcheckBox.setEnabled(True)
        self.DumpcheckBox.setChecked(True)
        self.DumpcheckBox.setObjectName("DumpcheckBox")
        self.verticalLayout_4.addWidget(self.DumpcheckBox)
        self.horizontalLayout_3.addLayout(self.verticalLayout_4)
        self.line_5 = QtWidgets.QFrame(CustomWidget)
        self.line_5.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_5.setObjectName("line_5")
        self.horizontalLayout_3.addWidget(self.line_5)
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.label_5 = QtWidgets.QLabel(CustomWidget)
        self.label_5.setObjectName("label_5")
        self.verticalLayout_5.addWidget(self.label_5)
        self.checkBox_4 = QtWidgets.QCheckBox(CustomWidget)
        self.checkBox_4.setEnabled(True)
        self.checkBox_4.setChecked(True)
        self.checkBox_4.setObjectName("checkBox_4")
        self.verticalLayout_5.addWidget(self.checkBox_4)
        self.horizontalLayout_3.addLayout(self.verticalLayout_5)
        self.line_6 = QtWidgets.QFrame(CustomWidget)
        self.line_6.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_6.setObjectName("line_6")
        self.horizontalLayout_3.addWidget(self.line_6)
        self.horizontalLayout_16.addLayout(self.horizontalLayout_3)
        spacerItem1 = QtWidgets.QSpacerItem(48, 51, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_16.addItem(spacerItem1)
        self.line_11 = QtWidgets.QFrame(CustomWidget)
        self.line_11.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_11.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_11.setObjectName("line_11")
        self.horizontalLayout_16.addWidget(self.line_11)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.label_6 = QtWidgets.QLabel(CustomWidget)
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_5.addWidget(self.label_6)
        self.numscomboBox = QtWidgets.QComboBox(CustomWidget)
        self.numscomboBox.setObjectName("numscomboBox")
        self.numscomboBox.addItem("")
        self.numscomboBox.addItem("")
        self.numscomboBox.addItem("")
        self.horizontalLayout_5.addWidget(self.numscomboBox)
        self.verticalLayout_6.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.Iplabel_2 = QtWidgets.QLabel(CustomWidget)
        self.Iplabel_2.setObjectName("Iplabel_2")
        self.horizontalLayout_4.addWidget(self.Iplabel_2)
        self.IntervallineEdit = QtWidgets.QLineEdit(CustomWidget)
        self.IntervallineEdit.setObjectName("IntervallineEdit")
        self.horizontalLayout_4.addWidget(self.IntervallineEdit)
        self.verticalLayout_6.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_7.addLayout(self.verticalLayout_6)
        self.line_7 = QtWidgets.QFrame(CustomWidget)
        self.line_7.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_7.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_7.setObjectName("line_7")
        self.horizontalLayout_7.addWidget(self.line_7)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.Iplabel = QtWidgets.QLabel(CustomWidget)
        self.Iplabel.setObjectName("Iplabel")
        self.horizontalLayout.addWidget(self.Iplabel)
        self.IplineEdit = QtWidgets.QLineEdit(CustomWidget)
        self.IplineEdit.setMaxLength(15)
        self.IplineEdit.setObjectName("IplineEdit")
        self.horizontalLayout.addWidget(self.IplineEdit)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.Portlabel = QtWidgets.QLabel(CustomWidget)
        self.Portlabel.setObjectName("Portlabel")
        self.horizontalLayout_2.addWidget(self.Portlabel)
        self.PortlineEdit = QtWidgets.QLineEdit(CustomWidget)
        self.PortlineEdit.setMaxLength(5)
        self.PortlineEdit.setObjectName("PortlineEdit")
        self.horizontalLayout_2.addWidget(self.PortlineEdit)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_7.addLayout(self.verticalLayout)
        self.line_8 = QtWidgets.QFrame(CustomWidget)
        self.line_8.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_8.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_8.setObjectName("line_8")
        self.horizontalLayout_7.addWidget(self.line_8)
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.StartpushButton = QtWidgets.QPushButton(CustomWidget)
        self.StartpushButton.setObjectName("StartpushButton")
        self.gridLayout.addWidget(self.StartpushButton, 0, 0, 1, 1)
        self.StoppushButton = QtWidgets.QPushButton(CustomWidget)
        self.StoppushButton.setEnabled(False)
        self.StoppushButton.setObjectName("StoppushButton")
        self.gridLayout.addWidget(self.StoppushButton, 0, 1, 1, 1)
        self.RestoreushButton = QtWidgets.QPushButton(CustomWidget)
        self.RestoreushButton.setObjectName("RestoreushButton")
        self.gridLayout.addWidget(self.RestoreushButton, 1, 1, 1, 1)
        self.SavepushButton = QtWidgets.QPushButton(CustomWidget)
        self.SavepushButton.setEnabled(False)
        self.SavepushButton.setObjectName("SavepushButton")
        self.gridLayout.addWidget(self.SavepushButton, 1, 0, 1, 1)
        self.horizontalLayout_7.addLayout(self.gridLayout)
        self.line_35 = QtWidgets.QFrame(CustomWidget)
        self.line_35.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_35.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_35.setObjectName("line_35")
        self.horizontalLayout_7.addWidget(self.line_35)
        self.horizontalLayout_16.addLayout(self.horizontalLayout_7)
        self.verticalLayout_7.addLayout(self.horizontalLayout_16)
        self.verticalLayout_9.addLayout(self.verticalLayout_7)

        self.retranslateUi(CustomWidget)
        QtCore.QMetaObject.connectSlotsByName(CustomWidget)

    def retranslateUi(self, CustomWidget):
        _translate = QtCore.QCoreApplication.translate
        CustomWidget.setWindowTitle(_translate("CustomWidget", "Form"))
        self.label_11.setText(_translate("CustomWidget", "TBAT:"))
        self.label_7.setText(_translate("CustomWidget", "VBUS:"))
        self.label_12.setText(_translate("CustomWidget", "IBAT:"))
        self.label_13.setText(_translate("CustomWidget", "VBAT:"))
        self.label_10.setText(_translate("CustomWidget", "ICPin:"))
        self.label_9.setText(_translate("CustomWidget", "VCPin:"))
        self.label_8.setText(_translate("CustomWidget", "IBUS:"))
        self.label_14.setText(_translate("CustomWidget", "TIME:"))
        self.label_2.setText(_translate("CustomWidget", "  显示方式"))
        self.DisplaycheckBox.setText(_translate("CustomWidget", "堆积/滚动"))
        self.label_3.setText(_translate("CustomWidget", " LOG开关"))
        self.LogcheckBox.setText(_translate("CustomWidget", "ON/OFF"))
        self.label_4.setText(_translate("CustomWidget", "  DUMPER"))
        self.DumpcheckBox.setText(_translate("CustomWidget", "ON/OFF"))
        self.label_5.setText(_translate("CustomWidget", "  待定"))
        self.checkBox_4.setText(_translate("CustomWidget", "ON/OFF"))
        self.label_6.setText(_translate("CustomWidget", "数据显示方式:"))
        self.numscomboBox.setItemText(0, _translate("CustomWidget", "显示最新数据"))
        self.numscomboBox.setItemText(1, _translate("CustomWidget", "显示最大数据"))
        self.numscomboBox.setItemText(2, _translate("CustomWidget", "显示游标数据"))
        self.Iplabel_2.setText(_translate("CustomWidget", "采集间隔(ms):"))
        self.IntervallineEdit.setText(_translate("CustomWidget", "1000"))
        self.Iplabel.setText(_translate("CustomWidget", "IP地址:"))
        self.IplineEdit.setText(_translate("CustomWidget", "192.168.1.111"))
        self.Portlabel.setText(_translate("CustomWidget", "  端口:"))
        self.PortlineEdit.setText(_translate("CustomWidget", "8106"))
        self.StartpushButton.setText(_translate("CustomWidget", "开始"))
        self.StoppushButton.setText(_translate("CustomWidget", "停止"))
        self.RestoreushButton.setText(_translate("CustomWidget", "回放"))
        self.SavepushButton.setText(_translate("CustomWidget", "保存"))

from pyqtgraph import PlotWidget


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个使用PyQtGraph进行多线程绘图的示例代码: ```python from PyQt5.QtWidgets import QApplication, QMainWindow, QGridLayout, QWidget from PyQt5.QtCore import Qt, QThread, pyqtSignal import pyqtgraph as pg import numpy as np import time class Worker(QThread): update_signal = pyqtSignal(int) def __init__(self, parent=None): super().__init__(parent) self.running = True def run(self): counter = 0 while self.running: self.update_signal.emit(counter) counter += 1 time.sleep(0.05) def stop(self): self.running = False self.wait() class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # 创建一个 Worker 实例 self.worker = Worker() # 创建一个 PyQTGraph 图形部件 self.plot_widget = pg.PlotWidget() # 设置图形部件的 X、Y 轴范围 self.plot_widget.setRange(xRange=[0, 100], yRange=[0, 100]) # 创建一个 PyQTGraph 图形项 self.plot_item = self.plot_widget.getPlotItem() # 创建一个曲线项,并将其添加到图形部件中 self.curve_item = self.plot_item.plot() # 将图形部件添加到主窗口中 central_widget = QWidget() layout = QGridLayout(central_widget) layout.addWidget(self.plot_widget) self.setCentralWidget(central_widget) # 连接 Worker 的信号和槽函数 self.worker.update_signal.connect(self.update_curve) # 启动 Worker 线程 self.worker.start() def closeEvent(self, event): # 停止 Worker 线程 self.worker.stop() event.accept() def update_curve(self, counter): # 生成新的曲线数据 x = np.arange(100) y = np.sin(2 * np.pi * (x + counter) / 100) # 更新曲线项的数据 self.curve_item.setData(x=x, y=y) if __name__ == '__main__': app = QApplication([]) window = MainWindow() window.show() app.exec_() ``` 这个示例代码创建了一个多线程PyQTGraph 应用程序,它会在一个 PyQTGraph 图形部件中绘制一个正弦曲线,并且使用一个 QThread 子类来更新曲线数据。在这个示例中,我们创建了一个 Worker 类,它包含了一个用于生成新数据并更新曲线的 run() 方法。我们还实现了一个 stop() 方法,以便在应用程序关闭时停止线程。在主窗口中,我们创建了一个 PyQTGraph 图形部件,并在其中创建了一个曲线项。我们还连接了 Worker 的信号和槽函数,以便在新数据可用时更新曲线。最后,我们启动了 Worker 线程,并在主窗口关闭时停止它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值