Herramienta de análisis versión QCustomPlot2

        Esta semana, me di cuenta principalmente de la migración del control de dibujo de pyqtgraph a QCustomPlot 2. La sensación general es que, en primer lugar, se dice que este control de dibujo proviene de las manos de un gran maestro y, por supuesto, la calidad no es dijo. La ecología qt de cpp es muy popular, porque solo encontré un python en Internet. Sí, los demás son todos códigos de versión cpp. Aunque pocas personas usan python, no puede ocultar la brillantez del gran dios. Aunque hay algunos baches en el proceso de migración esta semana, al final, todas las funciones implementadas previamente en pyqtgraph se implementaron con éxito. Se ha implementado en plot2. Debo decir que al usar este control para lograr la misma función, el código de implementación no es solo reducido, pero hay algunos problemas Básicamente, no se encontraron errores en el control en sí, a diferencia de pyqtgraph, que tiene errores obvios (por supuesto, también puede ser Mi comida), al mismo tiempo, el problema de rendimiento que apareció en pyqtgraph se ha ido en este control. Cuando pyqtgraph dibuja un diagrama de dispersión, se atascará mucho cuando haya demasiados datos, pero el gráfico de líneas es muy fluido. No sé cuál es el problema. (# Sin embargo, básicamente hay no hay diferencia en el rendimiento al dibujar diagramas de dispersión y gráficos de líneas en QCustomPlot2) . Permítanme corregir esto. El diagrama de dispersión de este control también tiene problemas cuando la cantidad de datos es grande, especialmente cuando el rastreador se mueve. Debería ser igual que pyqtgraph Parece que solo podemos esperar para opengl, pero es un poco problemático compilar el soporte de opengl por nosotros mismos. Echemos un vistazo más tarde, pero la función sigue siendo bastante perfecta.

No hay mucho que decir, pon el código:

from calendar import c
from datetime import timedelta
from hashlib import new
import sys
import json
import pickle
#import cgitb
import os
import time
import multiprocessing
from unicodedata import name

import numpy as np
from pandas._libs.tslibs.timestamps import Timestamp
from ctypes.wintypes import MSG
import random
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QGridLayout,QTabWidget,
                             QHBoxLayout, QVBoxLayout,QLabel, QComboBox,QPushButton,
                             QDateEdit, QSpacerItem,QFrame, QSizePolicy, QSplitter,
                             QRadioButton, QGroupBox,QCheckBox,QLineEdit, QAction,
                             QFileDialog,QListView,QListWidget,QListWidgetItem,QMenu,
                             QProgressBar,QProgressDialog,QMessageBox,QAbstractItemView,
                             QSplashScreen)
from PyQt5.QtCore import Qt, QDate, QRect,QSize
from PyQt5 import QtCore
from PyQt5.QtGui import QIcon, QBitmap, QPainter, QPixmap, QCursor, QMovie,QLinearGradient
import pyqtgraph as pg
from pyqtgraph import mkPen,DateAxisItem,AxisItem
import QCustomPlot2 as qcp
from QCustomPlot2 import (QCustomPlot,QCP,QCPAxisRect,QCPAxis,QCPScatterStyle,QCPItemPosition,
                        QCPAxisTickerDateTime,QCPLineEnding,QCPItemTracer,QCPItemLine,QCPGraph,
                        QCPItemStraightLine)


from formated_axis import FormatedAxis
from DropListWidget import DropInList
from utils import *
from conf import *
from MyComboCheckBox import *
from DailyAnalysisDialog import *
from DurableAnalysisDialog import *
from FormatConversionDialog import *
from BleedDownAnalysisDialog import *
from PolarAnalysisDialog import *
from DropListWidget import *
from task_threads import *
from LittleWidgets import Cursor
import images
#from QCandyUi.CandyWindow import colorful



class MainWindow(QMainWindow):

    def __init__(self,*args):
        
        super().__init__()
        self.time_index = []
        self.ydata = [[],[]]
        self.select_data = []
        self.y_axis = ['sPDU_StkOut_iSTK_A','']
        self.zdata = {}
        self.all_signals = []
        self.have_sig = ['Time']
        self.tx = 0
        self.ty = 0
        self.plt_list = []

        self.ax_list = []

        self.plt_color_list = []
        self.graph_list = []
        self.line_style = 'line'
        self.plt_gph_map = {}
        self.draw_sig = []
        self.axis_layout_list = []
        self.x_col = 'index'
        self.theme = "black"
        self.color_map = color_map
        self.mouse_ispressed = False
        self.vline1 = None
        self.conf_data = {}
        self.merge_cols = []
        self._init_ui()
        self.show()
        if len(args[0]) > 1:
            self.f_list = args[0][1:]
        self.load_data()
    

    def _init_ui(self):
        self.setWindowTitle('分析工具')
        self.resize(1200,700)
        self.setWindowIcon(QIcon(':/icon/数据分析.ico'))
        qwg  = QWidget()
        left_wdgt = QWidget()
        leftarea_layout = QVBoxLayout()

        #全局布局
        wlayout = QVBoxLayout()

        #单线按钮
        self.tool_bar = self.addToolBar("单线")
        single_line = QAction(QIcon(':/icon/单线.png'), '单线', self)
        self.tool_bar.addAction(single_line)
        #双线按钮
        multi_line = QAction(QIcon(':/icon/双线.png'), '双线', self)
        self.tool_bar.addAction(multi_line)
        self.multi_flag = False

        #重置按钮
        reset_button = QAction(QIcon(':/icon/reset.png'), '重置(F)', self)
        reset_button.setShortcut(QKeySequence("f"))
        self.tool_bar.addAction(reset_button)

        #折线图按钮
        line_button = QAction(QIcon(':/icon/折线图.ico'), '折线图', self)
        line_button.setShortcut(QKeySequence("l"))
        self.tool_bar.addAction(line_button)

        #散点图按钮
        scatter_button = QAction(QIcon(':/icon/散点图.ico'), '散点图', self)
        scatter_button.setShortcut(QKeySequence("s"))
        self.tool_bar.addAction(scatter_button)

        #点线图按钮
        ls_button = QAction(QIcon(':/icon/点线图.ico'), '点线图', self)
        ls_button.setShortcut(QKeySequence("l+s"))
        self.tool_bar.addAction(ls_button)

        #导出按钮
        export_button = QAction(QIcon(':/icon/导出.ico'), '导出', self)
        #ls_button.setShortcut(QKeySequence("Ctrl + e"))
        self.tool_bar.addAction(export_button)

        #主题按钮
        theme_button = QAction(QIcon(':/icon/主题.png'), '主题', self)
        theme_button.setShortcut(QKeySequence("f"))
        #self.tool_bar.addAction(theme_button)
        #self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.tool_bar.actionTriggered.connect(self.toolbtnpressed)
        #wlayout.addWidget(self.tool_bar)
        self.splitter = QSplitter(Qt.Horizontal)
        self.search_box = QLineEdit()
        self.search_box.textChanged.connect(self.search_sig)
        self.leftarea = QTabWidget()
        self.siglist = QListWidget()
        self.siglist.setDragEnabled(True)
        self.siglist.setAcceptDrops(True)
        #self.siglist.setStyleSheet('QListWidget {border:none;    }')
        self.siglist.itemClicked.connect(self.item_clicked)
        self.siglist.itemDoubleClicked.connect(self.push_to_select)
        self.siglist.setContextMenuPolicy(Qt.CustomContextMenu)
        self.siglist.customContextMenuRequested[QtCore.QPoint].connect(self.my_list_widget_context)
        
        #选择信号列表
        self.select_widget = QWidget()
        v_layout = QVBoxLayout()
        self.time_label = QLabel("time")
        
        self.select_sig = DropInList()
        self.select_sig.enter.connect(self.draw_chart_mul2)
        self.select_sig.select_state.connect(self.select_state)
        self.select_sig.itemClicked.connect(self.switch_sig)
        self.select_sig.setContextMenuPolicy(Qt.CustomContextMenu)
        self.select_sig.customContextMenuRequested[QtCore.QPoint].connect(self.select_sig_context)
        #self.select_sig.setStyleSheet('QListWidget {border:none;    }')
        v_layout.addWidget(self.select_sig)
        v_layout.addWidget(self.time_label)
        #v_layout.setSpacing(5)
        v_layout.setContentsMargins(0,0,5,0)
        self.select_widget.setLayout(v_layout)
        #self.select_sig.setAcceptDrops(Tr)
        self.search_result = QListWidget()
        self.search_result.setDragEnabled(True)
        self.search_result.itemDoubleClicked.connect(self.push_to_select)
        self.search_result.setContextMenuPolicy(Qt.CustomContextMenu)
        self.search_result.customContextMenuRequested[QtCore.QPoint].connect(self.my_search_list_widget_context)
        #self.search_result.setStyleSheet('QListWidget {border:none;    }')
        self.leftarea.addTab(self.siglist,'全部信号')
        self.leftarea.addTab(self.search_result,'搜索结果')
        
        

        leftarea_layout.addWidget(self.search_box)
        leftarea_layout.addWidget(self.leftarea)
        #leftarea_layout.setSpacing(5)
        leftarea_layout.setContentsMargins(0,0,5,0)
        left_wdgt.setLayout(leftarea_layout)
        self.splitter.addWidget(left_wdgt)

        
        self.splitter.addWidget(self.select_widget)

        self.status_bar = self.statusBar()
        self.status_bar.showMessage("状态栏")
        splt = self._my_line()

        #绘图
        self.graphic_widget_init()
        
        self.g_wdgt = QWidget()
        print(self.win)
        #self.g_wdgt.addItem(self.win)
        self.pw = pg.GraphicsView()
        self.pw.setCentralWidget(self.win)
        #注意plt_init函数,必须放在self.pw.setCentralWidget(self.win)后面执行,否则self.pltwgt没有scene()方法返回None
        



        self.line_plot = QCustomPlot()
        self.plt_init()

        self.splitter.addWidget(self.line_plot)

        self.splitter.setStretchFactor(0, 0)
        self.splitter.setStretchFactor(1, 0)
        self.splitter.setStretchFactor(2, 1)

        #第一层

        self._zero_layer()

        wlayout.addWidget(self.splitter)

        wlayout.addWidget(self.status_bar)

        self.qssfile = ":/style/style.qss"
        self.qssstyle = read_qss(self.qssfile)
        self.setStyleSheet(self.qssstyle)
        qwg.setLayout(wlayout)
        self.setCentralWidget(qwg)
    
    def toolbtnpressed(self,tool):
        print(tool.text())
        tool_name = tool.text()
        if tool_name == "双线":
            if not self.multi_flag:
                self.multi_flag = True
                
                self.vline1 = QCPItemStraightLine(self.line_plot)
                self.vline1.setLayer("overlay")
                linesPen = QPen(QColor("#FFFF00"),1,Qt.PenStyle.SolidLine)
                lineSelectedPen = QPen(QColor("#ffffff"),1,Qt.PenStyle.SolidLine)
                self.vline1.setPen(linesPen)
                self.vline1.setSelectedPen(lineSelectedPen)
                self.vline1.setClipToAxisRect(True)
                
                self.vline1.point1.setTypeX(QCPItemPosition.ptPlotCoords)
                self.vline1.point1.setTypeY(QCPItemPosition.ptPlotCoords)
                self.vline1.point2.setTypeX(QCPItemPosition.ptPlotCoords)
                self.vline1.point2.setTypeY(QCPItemPosition.ptPlotCoords)
                self.vline1.setVisible(True)
                self.vline1.setSelectable(True)
                self.vline1.selectionChanged.connect(self.line1_selection_changed)
                print(self.x)
                self.vline1.point1.setCoords(self.x1 +self.x1*0.5 , 100)
                self.vline1.point2.setCoords(self.x1 +self.x1*0.5, 0)
                
            else:
                self.multi_flag = False
                self.line_plot.removeItem(self.vline1)
                self.vline1 = None
            self.line_plot.replot()
        if tool_name == "重置(F)":
            self.reset_plt()
        
        if tool_name == "主题":
            self.switch_theme()
        if tool_name == "散点图":
            self.line_style = 'scatter'
            self.set_line_style('scatter')
        if tool_name == "折线图":
            self.line_style = 'line'
            self.set_line_style('line')
        if tool_name == "点线图":
            self.line_style = 'ls'
            self.set_line_style('ls')
        if tool_name == "导出":
            filepath, ftype = QFileDialog.getSaveFileName(self, '文件保存', '/', '.png;;.pdf;;.jpg')
            print(ftype)
            
            if ftype == '.png':
                if not filepath.endswith('.png'):
                    filepath += ftype
                self.line_plot.savePng(filepath,self.line_plot.width(),self.line_plot.height())
            if ftype == '.jpg':
                if not filepath.endswith('.jpg'):
                    filepath += ftype
                self.line_plot.saveJpg(filepath,self.line_plot.width(),self.line_plot.height())
            if ftype == '.pdf':
                if not filepath.endswith('.pdf'):
                    filepath += ftype
                self.line_plot.savePdf(filepath,self.line_plot.width(),self.line_plot.height())
            show_message(self,"info","导出成功    ")

    def graph_selection_changed(self,res,idx,evt):
        print(res,evt)
        print(self.ax_list)
        self.graph = res
        for ax in self.ax_list:
            ax.setVisible(False)
        self.plt_gph_map[res].setVisible(True)
        self.qcp_rect.setRangeDragAxes([self.x_axis,self.plt_gph_map[res]])
        self.qcp_rect.setRangeZoomAxes([self.x_axis,self.plt_gph_map[res]])
        self.line_plot.replot()
        print("============after change============")

    def switch_theme(self):
        print("=======self.theme=======",self.theme)
        if self.theme == "black":
            pg.setConfigOption("background", "white")
            
            self.theme = "white"
        else:
            pg.setConfigOption("background", "black")
            self.theme = "black"

    def item_clicked(self,item):
        print("============item clicked=========",item)

    def switch_sig(self,sigitem):
        print(sigitem)
        print("=========self.merge_cols========",self.merge_cols)
        w = self.select_sig.itemWidget(sigitem)

        label = w.findChild(QLabel,"signame")
        signame = label.text()
        if signame in self.merge_cols:
            signame = signame + '_merge'
        chk = w.findChild(QCheckBox,"state")
        dest_idx = 0
        if chk.isChecked():
            for idx,graph in enumerate(self.graph_list):
                if graph.name == signame:
                    self.graph_selection_changed(graph,None,None)
                    break

        


    def select_sig_item(self,signame):
        item_widgt = QWidget()
        root = QHBoxLayout()
        chk = QCheckBox()
        chk.setChecked(True)
        chk.setObjectName("state")
        name_label = QLabel(signame)
        name_label.setObjectName("signame")
        #name_label.setFixedSize(40, 25)
        value_label = QLabel("=")
        value_label.setObjectName(signame+ "_value")
        root.addWidget(chk,0,Qt.AlignLeft)
        root.addWidget(name_label,1,Qt.AlignLeft)
        root.addWidget(value_label,0,Qt.AlignRight)
        item_widgt.setLayout(root)
        chk.stateChanged.connect(partial(self.select_sig.select_state_changed,signame,chk))
        return item_widgt

    def push_to_select(self,item):
        print(item)
        text = item.text()
        #self.select_sig.addItem(text)
        #idx = self.siglist.indexFromItem(item).row()
        #self.siglist.insertItem(idx,text)

        item_widgt = self.select_sig_item(text)
        new_item = QListWidgetItem()
        new_item.setSizeHint(QSize(100, 30))
        self.select_sig.addItem(new_item)  #插入本listwidget
        self.select_sig.setItemWidget(new_item,item_widgt)
        


    def select_state(self,signame,checked):
        #if checked:
        #    self.draw_sig.append(signame)
        #else:
        #    self.draw_sig.remove(signame)
        self.redraw(signame,checked)


    def search_sig(self,ctext):
        res = []
        self.search_result.clear()
        self.leftarea.setCurrentIndex(1)
        for item in self.all_cols:
            if ctext.lower() in item.lower():
                res.append(item)
        if res:
            self.search_result.addItems(res)

    def nativeEvent(self, eventType, msg):
        message = MSG.from_address(msg.__int__())
        if message.message == 0x0003:  # 窗口移动
            pass
        return False, 0


    def _zero_layer(self):

        self.menu = self.menuBar()
        self.file_menu = self.menu.addMenu("文件")
        self.file_menu.addAction("打开文件")
        self.file_menu.addAction("打开文件夹")
        self.file_menu.addAction("打开配置")
        self.file_menu.addAction("保存")
        self.file_menu.triggered[QAction].connect(self.processtrigger)
        #h0_wlayout.addWidget(self.menu)
        self.analysis_menu = self.menu.addMenu("分析")
        self.analysis_menu.addAction(QAction(QIcon(":/icon/耐久每日分析.ico"),"耐久每日分析",self))
        self.analysis_menu.addAction(QAction(QIcon(":/icon/耐久极化分析.ico"),"耐久极化分析",self))
        self.analysis_menu.addAction(QAction(QIcon(":/icon/分析.ico"),"单个极化分析",self))
        self.analysis_menu.addAction(QAction(QIcon(":/icon/耐久Bleeddown分析.ico"),"耐久Bleeddown分析",self))
        self.analysis_menu.triggered[QAction].connect(self.analysis_trigger)

        self.analysis_menu = self.menu.addMenu("数据处理")
        self.analysis_menu.addAction(QAction(QIcon(":/icon/格式转换.ico"),"格式转换",self))
        #self.analysis_menu.addAction(QAction(QIcon(":/耐久极化分析.ico"),"合并拆分",self))
        self.analysis_menu.triggered[QAction].connect(self.data_process)

    def data_process(self):
        self.fc_dlg = FormatConversionDialog()


    
    

    def processtrigger(self,q):
        if q.text() == "保存":
            filepath, type = QFileDialog.getSaveFileName(self, '文件保存', '/', 'json(*.json)')


            self.conf_data['file_list'] = self.f_list
            self.conf_data['select_sig'] = self.draw_sig
            self.conf_data['merge_cols'] = self.merge_cols
            self.conf_data['x_col'] = self.x_col
            self.conf_data['line_style'] = self.line_style

            
            open(filepath,'w').write(json.dumps(self.conf_data))
        elif q.text() == '打开配置':
            filename=QFileDialog.getOpenFileNames(self,'选择文件',os.getcwd(), "All Files(*);;eg Files(*.xlsx *.csv *.MDF)")
            json_list = filename[0]
            if json_list:
                try:
                    self.conf_f = json_list[0]
                    self.conf_content = json.loads(open(self.conf_f,'r').read())
                    print(self.conf_content)
                    self.f_list = self.conf_content["file_list"]
                    self.load_data()
                except Exception as e:
                    show_message(self,"err","文件读取失败" + str(e))
            
        elif q.text() == "打开文件":
            filename = QFileDialog.getOpenFileNames(self,'选择文件',os.getcwd(), "All Files(*);;eg Files(*.xlsx *.csv *.MDF)")
            self.f_list = filename[0]
            self.load_data()
            print(self.f_list)
        elif q.text() == "打开文件夹":
            self.data_dir=QFileDialog.getExistingDirectory(None,"选取文件夹","C:/")
            self.get_file_list()
            self.load_data()
            print(self.f_list)
        print("menu")

    def add_conf_sig(self):
        print("addconfsig",self.draw_sig)
        for sig in self.draw_sig:
            new_item = self.select_sig.select_sig_item(sig)
            item = QListWidgetItem()
            item.setSizeHint(QSize(130, 33))
            self.select_sig.addItem(item)  #插入本listwidget
            self.select_sig.setItemWidget(item,new_item)
            print("==========add sig=========",item)


    def load_data(self):


        '''self.loading_gif = QMovie('loading.gif')
        self.label.setMovie(self.loading_gif)
        self.loading_gif.start()'''

        if hasattr(self, 'f_list') and self.f_list:
            file_str = ",".join(self.f_list)
            self.dlg = QProgressDialog()
            self.dlg.setWindowIcon(QIcon(":/icon/加载中.ico"))
            self.dlg.setRange(0,100)
            self.dlg.setAutoClose(True)
            self.dlg.setWindowTitle("提示")
            self.dlg.setWindowModality(Qt.WindowModal)
            self.dlg.setLabelText('加载数据中')
            self.dlg.setCancelButtonText('取消')
            self.dlg.show()
            
            self.load_data_thread = LoadDataTheard(self.f_list)
            self.load_data_thread.res.connect(self.recieve_data)
            self.load_data_thread.progress.connect(self.update_progress)
            self.load_data_thread.start()
        #self.load_data()

    def clear_plt_sig(self):
        self.line_plot.clearPlottables()
        for i in range(self.line_plot.graphCount()):
            self.line_plot.removeGraph(i)
        
        self.line_plot.plotLayout().clear()
        self.line_plot.removeItem(self.tracer)
        self.line_plot.removeItem(self.vline)
        self.line_plot.replot()
        if hasattr(self, 'select_sig'):
            self.select_sig.clear()
        if hasattr(self, 'qcp_rect'):
            self.qcp_rect = None
        
        self.draw_sig = []
        self.plt_color_list = []
        self.ax_list = []
        #self.merge_cols = []
        self.plt_gph_map = {}
        self.graph_list = []

    def clear_plt(self):
        self.line_plot.clearPlottables()
        for i in range(self.line_plot.graphCount()):
            self.line_plot.removeGraph(i)
        

        if hasattr(self, 'qcp_rect'):
            self.qcp_rect = None
        self.line_plot.plotLayout().clear()
        self.line_plot.removeItem(self.tracer)
        self.line_plot.removeItem(self.vline)
        #self.line_plot.removeItem(self.vline)
        self.line_plot.replot()
        


        
        self.plt_color_list = []

        self.ax_list = []
        #self.merge_cols = []
        self.graph_list = []
        self.plt_gph_map = {}

    def recieve_data(self,data):
        self.clear_plt_sig()
        #self.plt_init()
        
        self.qcp_rect_init()

        self.cursor_init()
        self.tracer_init()
        self.line_plot.replot()
        #self.line_plot.plotLayout().clear()
        self.total_data = data
        self.date_str = extract_date(self.f_list[0])
        self.all_cols = self.total_data.columns.tolist()
        self.siglist.addItems(self.all_cols)
        if 'Time' in self.total_data:
            self.time_index = self.total_data['Time']
        if 'sPDU_StkOut_iSTK_A' in self.total_data:
            
            self.ydata[0] = self.total_data['sPDU_StkOut_iSTK_A']
            
            
        else:
            show_message(self,"err","sPDU_StkOut_iSTK_A信号未找到")
        if hasattr(self, "conf_f") and self.conf_f:
            print("==========self.conf_f=======")

            self.draw_sig = self.conf_content["select_sig"]
            self.merge_cols = self.conf_content["merge_cols"]
            self.x_col = self.conf_content['x_col']
            self.line_style = self.conf_content.get('line_style','line')


            self.add_conf_sig()
            self.redraw_plt()
            self.merge_yaxis()
            self.conf_f = ""


        


    def update_progress(self,prog):
        print("progress" + str(prog))
        self.dlg.setValue(prog)


    def get_file_list(self):
        self.f_list = get_flist(self.data_dir)
    
    def analysis_trigger(self,q):
        if q.text() == "耐久每日分析":
            print("耐久每日分析")
            if hasattr(self,'total_data'):
                self.ad = DailyAnalysisDialog(self.total_data)
            else:
                self.ad = DailyAnalysisDialog([])
            

        elif q.text() == '耐久极化分析':
            self.durable = DurableAnalysisDialog([])
            print("耐久极化分析")
        elif q.text() == '单个极化分析':
            self.durable = PolarAnalysisDialog()
            print("单个极化分析")
        elif q.text() == '耐久极化分析':
            self.bleed_down = BleedDownAnalysisDialog([])
            print("耐久极化分析")

    def redraw(self,signame,chk):
        for idx,graph in enumerate(self.graph_list):
            if graph.name == signame:
                print("========name==========",signame,chk)
                if chk:
                    self.graph_list[idx].setVisible(True)
                    selected_items = self.select_sig.selectedItems()
                        
                    for item in selected_items:
                        w = self.select_sig.itemWidget(item)
                        label = w.findChild(QLabel,"signame")
                        if label.text() == signame:
                            self.graph_selection_changed(graph,None,None)


                else:
                    self.graph_list[idx].setVisible(False)
                    yaxis = self.plt_gph_map.get(graph)
                    yaxis.setVisible(False)
        self.line_plot.replot()

    
    

    def draw_chart_mul2(self,items):
        print("=============draw_chart_mul2===========",items)

        self.draw_sig_temp = []

        if hasattr(self, "total_data"):

            if self.x_col == 'index':
                self.zdata = self.total_data.copy()

            for item in items:

                w = self.select_sig.itemWidget(item)
                check_box = w.findChild(QCheckBox,"state")
                if check_box and check_box.isChecked():

                    label = w.findChild(QLabel,"signame")
                    text = label.text()
                    self.draw_sig_temp.append(text)
                    

            if "" in self.draw_sig:
                self.draw_sig.remove("")


            self.select_sig_before = len(self.graph_list)+1 - len(self.draw_sig_temp)
            self.select_sig_total = len(self.graph_list)+1
            for index in range(self.select_sig_before,self.select_sig_total):
                #self.vb_ax_init(index)
                #print(index)
                col = self.draw_sig_temp[index-self.select_sig_before]
                self.draw_sig.append(col)
                color = self.color_map.get(col,get_color())
                self.vb_ax_init(index,self.x_col,self.zdata[col],color,col)


    


    def graphic_widget_init(self):
        #pg.setConfigOption("background", "black")
        #plt = pg.PlotWidget()
        #win对象一定要保留,不保留plt对象没了容器,后面就没法添加子控件了
        #self.win = pg.GraphicsLayoutWidget(show=True)
        self.win = pg.GraphicsLayout()
        #self.win.setContentsMargins(0, 0, 0, 0)
        self.win.setSpacing(0)
        self.win.setMinimumWidth(0)
        
        #self.win.resize(913,466)
        
        

    def set_background(self):
        plot_gradient = QLinearGradient()

        plot_gradient.setStart(0, 0); 

        plot_gradient.setFinalStop(0, 350); 

        plot_gradient.setColorAt(0, QColor(0, 0, 0)); 

        plot_gradient.setColorAt(1, QColor(0, 0, 0)); 

        self.line_plot.setBackground(plot_gradient)
    

    def set_axis_color(self,axis,color):
        axis.setLabelColor(QColor(color)); 
        axis.setTickLabelColor(QColor(color)); 
        axis.setBasePen(QPen(QColor(color),1,Qt.PenStyle.SolidLine)); 
        axis.setTickPen(QPen(QColor(color))); 
        axis.setSubTickPen(QPen(QColor(color)))
        


    def plt_init(self):

        self.line_plot.plotLayout().clear()
        
        
        self.line_plot.plottableClick.connect(self.graph_selection_changed)
        self.line_plot.setInteraction(QCP.iRangeDrag)
        self.line_plot.setInteraction(QCP.iRangeZoom)
        self.line_plot.mouseMove.connect(self.mouse_move)
        self.line_plot.mousePress.connect(self.mouse_pressed)
        #self.line_plot.mousePress.connect(self.mouse_ispressed)
        self.line_plot.mouseRelease.connect(self.mouse_release)
        self.set_background()
        
        
        
        self.qcp_rect_init()

        self.cursor_init()
        self.tracer_init()
        self.line_plot.replot()
    
    def qcp_rect_init(self):
        self.qcp_rect = QCPAxisRect(self.line_plot,True)
        self.line_plot.plotLayout().addElement(0,0,self.qcp_rect)
        self.x_axis = self.qcp_rect.axis(QCPAxis.atBottom)
        
        self.set_axis_color(self.line_plot.xAxis,"#ffffff")
        self.set_axis_color(self.line_plot.yAxis,"#ffffff")
        self.line_plot.xAxis.grid().setPen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))
        self.line_plot.xAxis.grid().setSubGridVisible(True)
        self.line_plot.xAxis.grid().setLayer("grid")
        self.line_plot.xAxis.grid().setSubGridPen(QPen(QColor("#003000"),1,Qt.PenStyle.DashLine))
        self.line_plot.xAxis.setTickLength(0,6)
        self.line_plot.xAxis.setSubTickLength(0,3)
        self.line_plot.xAxis.grid().setZeroLinePen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))


        self.line_plot.yAxis.grid().setPen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))
        self.line_plot.yAxis.grid().setSubGridVisible(True)
        self.line_plot.yAxis.grid().setSubGridPen(QPen(QColor("#003000"),1,Qt.PenStyle.DashLine))
        self.line_plot.yAxis.grid().setZeroLinePen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))
        self.line_plot.yAxis.grid().setLayer("grid")
        self.line_plot.yAxis.setTickLength(0,6)
        self.line_plot.yAxis.setSubTickLength(0,3)
        self.line_plot.replot()
        

    def cursor_init(self):
        self.vline = QCPItemStraightLine(self.line_plot)
        self.vline.setLayer("overlay")
        linesPen = QPen(QColor("#00FFFF"),1,Qt.PenStyle.SolidLine)
        lineSelectedPen = QPen(QColor("#ffFFFF"),1,Qt.PenStyle.SolidLine)
        self.vline.setPen(linesPen)
        self.vline.setSelectedPen(lineSelectedPen)
        self.vline.setClipToAxisRect(True)
        
        self.vline.point1.setTypeX(QCPItemPosition.ptPlotCoords)
        self.vline.point1.setTypeY(QCPItemPosition.ptPlotCoords)
        self.vline.point2.setTypeX(QCPItemPosition.ptPlotCoords)
        self.vline.point2.setTypeY(QCPItemPosition.ptPlotCoords)
        self.vline.setVisible(False)
        self.vline.setSelectable(True)
        self.vline.selectionChanged.connect(self.line_selection_changed)


    def tracer_init(self):
        self.tracer = QCPItemTracer(self.line_plot)

        self.tracer.setPen(QPen(QColor("#ffffff"),1,Qt.PenStyle.DashLine))
        self.tracer.setStyle(QCPItemTracer.TracerStyle.tsCrosshair)


    def line1_selection_changed(self,selected):
        
        print("=======selected=====",selected)
        if not selected:
            self.line_plot.setInteraction(QCP.iRangeDrag,True)

    def line_selection_changed(self,selected):
        print(selected)
        if not selected:
            self.line_plot.setInteraction(QCP.iRangeDrag,True)

    def mouse_move(self,event):

        if self.line_plot.xAxis is not None:
            
            #下面的代码很关键
            self.x = self.line_plot.xAxis.pixelToCoord(event.pos().x())
            if self.mouse_ispressed and (self.vline.selected() or (self.vline1 and self.vline1.selected())):
                
                #print(x)
                self.tracer.setGraph(self.graph) #设置游标吸附于指定曲线

                self.tracer.setGraphKey(self.x); #将游标横坐标(key)设置成刚获得的横坐标数据x
                self.tracer.setInterpolating(True); #游标的纵坐标可以通过曲线数据线性插值自动获得
                self.tracer.updatePosition(); #使得刚设置游标的横纵坐标位置生效
                if self.vline.selected():
                    self.x1 = self.x
                    self.vline.point1.setCoords(self.x, 100)
                    self.vline.point2.setCoords(self.x, 0)
                elif self.vline1.selected():
                    self.x2 = self.x
                    self.vline1.point1.setCoords(self.x, 100)
                    self.vline1.point2.setCoords(self.x, 0)
                self.vline_moved(self.vline)
                self.line_plot.replot()





    def mouse_pressed(self,event):
        self.mouse_ispressed = True
        x = self.line_plot.xAxis.pixelToCoord(event.pos().x())
        
        dis = self.vline.selectTest(event.pos(),True)
        if hasattr(self,"vline1") and self.vline1:
            dis1 = self.vline1.selectTest(event.pos(),True)
            if dis1 < 5:
                self.vline1.setSelected(True)
                print("===========dis1==========",dis1)  
                self.line_plot.setInteraction(QCP.iRangeDrag,False)
                self.tracer.setVisible(True)
        
        print(event)
        if dis < 5:
            self.vline.setSelected(True)
            print(dis)
        
        #self.line_plot.setCurrentLayer("overlay")
            self.line_plot.setInteraction(QCP.iRangeDrag,False)

        
            
            self.tracer.setVisible(True)

        if not self.vline.visible():
            self.vline.setVisible(True)
            self.vline.point1.setCoords(x, 100)
            self.vline.point2.setCoords(x, 100 - 100.0)
            self.x1 = x
        self.line_plot.replot()

    def mouse_release(self,event):
        print("release")
        self.tracer.setVisible(False)
        self.mouse_ispressed = False
        self.vline.setSelected(False)
        if hasattr(self,"vline1") and self.vline1:
            self.vline1.setSelected(False)
        self.line_plot.setInteraction(QCP.iRangeDrag,True)
        self.line_plot.replot()

        
    

    def vline_moved(self,vline):
        #print(vline.value())
        print()
        if self.x_col == 'index':
            v = int(self.x)
        else:
            v = round(self.x,2)
        

        

        if self.multi_flag:
            #print(self.multi_flag)
            try:

                self.x1_value = (self.zdata[self.x_col] - self.x1).abs().idxmin()

                self.x2_value = (self.zdata[self.x_col] - self.x2).abs().idxmin()
                
                for i in range(self.select_sig.count()):

                    item = self.select_sig.item(i)
                    w = self.select_sig.itemWidget(item)

                    label = w.findChild(QLabel,"signame")
                    signame = label.text()
                    value_label = w.findChild(QLabel,"value")
                    if self.x1_value < self.zdata.shape[0]:
                        
                        value_label.setText("= %.2f" % (self.zdata[signame][self.x2_value] - self.zdata[signame][self.x1_value]))
                        self.time_label.setText("= %.21s" % (self.zdata['Time'][self.x2_value] - self.zdata['Time'][self.x1_value]))
            except:
                if vline is self.vline:
                    self.x1_value = self.x1
                else:
                    self.x2_value = self.x2
        else:
            self.x1_value = (self.zdata[self.x_col] - self.x1).abs().idxmin()
            for i in range(self.select_sig.count()):

                item = self.select_sig.item(i)
                w = self.select_sig.itemWidget(item)

                label = w.findChild(QLabel,"signame")
                signame = label.text()
                value_label = w.findChild(QLabel,"value")
                if self.x1_value < self.zdata.shape[0]:
                    if isinstance(self.zdata[signame][self.x1_value],float):
                        value_label.setText("= %.2f" % self.zdata[signame][self.x1_value])
                    else:
                        value_label.setText("= %s" % self.zdata[signame][self.x1_value])
                    self.time_label.setText("time = %.21s" % self.zdata['Time'][self.x1_value])


    


    def state_changed(self,aa):
        print("state changed",aa)


    def reset_plt(self):
        '''绘图重置,主要是重置x轴坐标为index'''
        self.clear_plt()
        self.qcp_rect_init()

        self.cursor_init()
        self.tracer_init()
        self.line_plot.replot()
        self.draw_sig_temp = []

        
        if hasattr(self, "total_data"):

            self.zdata = self.total_data.copy()
            
            

                    

            if "" in self.draw_sig:
                self.draw_sig.remove("")
            #for col in self.draw_sig:

            #    self.zdata[col] = self.total_data[col]
            self.select_sig_before = self.select_sig.count() - len(self.draw_sig)
            self.select_sig_total = self.select_sig.count()
            for index,col in enumerate(self.draw_sig):
                #self.vb_ax_init(index)
                print(index)
                color = self.color_map.get(col,get_color())
                self.vb_ax_init(index,'index',self.zdata[col],color,col)
            for i in range(self.select_sig.count()):
                item = self.select_sig.item(i)
                w = self.select_sig.itemWidget(item)
                check_box = w.findChild(QCheckBox,"state")
                chk = check_box.isChecked()
                label = w.findChild(QLabel,"signame")
                signame = label.text()
                self.redraw(signame,chk)



    def redraw_plt(self):

        print("=======x_col========",self.x_col)
        self.clear_plt()
        self.qcp_rect_init()

        self.cursor_init()
        self.tracer_init()
        self.line_plot.replot()
        self.draw_sig_temp = []

        
        if hasattr(self, "total_data"):

            self.zdata = self.total_data.sort_values(by=self.x_col)
            #self.zdata = self.zdata.reset_index()
            
            for i in range(self.select_sig.count()):
                item = self.select_sig.item(i)
                w = self.select_sig.itemWidget(item)
                check_box = w.findChild(QCheckBox,"state")
                if check_box and check_box.isChecked():

                    label = w.findChild(QLabel,"signame")
                    text = label.text()
                    self.draw_sig_temp.append(text)

                    

            if "" in self.draw_sig:
                self.draw_sig.remove("")
            #for col in self.draw_sig:

            #    self.zdata[col] = self.total_data[col]
            self.select_sig_before = self.select_sig.count() - len(self.draw_sig_temp)
            self.select_sig_total = self.select_sig.count()
            for index,col in enumerate(self.draw_sig):
                #self.vb_ax_init(index)
                print(index)
                color = self.color_map.get(col,get_color())
                self.vb_ax_init(index,self.x_col,self.zdata[col],color,col)


    def my_list_widget_context(self, point):
        item = self.siglist.itemAt(point)
        if item:
            self.x_col = item.text()
            popMenu = QMenu()
            popMenu.addAction(QAction(u'设为x轴', self,triggered=self.redraw_plt))
            popMenu.exec_(QCursor.pos())
            print(self.x_col)
    
    def my_search_list_widget_context(self, point):
        item = self.search_result.itemAt(point)
        if item:
            self.x_col = item.text()
            popMenu = QMenu()
            popMenu.addAction(QAction(u'设为x轴', self,triggered=self.redraw_plt))
            popMenu.exec_(QCursor.pos())
            print(self.x_col)
    
    def select_sig_context(self, point):
        print("select_sig_context")
        
        selected_items = self.select_sig.selectedItems()
        item = self.select_sig.itemAt(point)
        popMenu = QMenu()
            
        if len(selected_items) > 1:
            popMenu.addAction(QAction(u'合并y轴', self,triggered=self.merge_yaxis))
        elif item:
            
            w = self.select_sig.itemWidget(item)

            label = w.findChild(QLabel,"signame")
            self.x_col = label.text()
            print("==========item========",item)
            print("==========item========",self.x_col)
            
            popMenu.addAction(QAction(u'设为x轴', self,triggered=self.redraw_plt))
        popMenu.exec_(QCursor.pos())


    def merge_yaxis(self):
        print("merge_yaxis")
        #self.merge_cols = []
        #如果self.merge_cols有值,应该时从conf中读取的
        if self.merge_cols:
            print(self.merge_cols)
            self.hide_merge_cols()
            self.create_merge_plt()
        else:
            merge_items = self.select_sig.selectedItems()
            for item in merge_items:
                w = self.select_sig.itemWidget(item)

                label = w.findChild(QLabel,"signame")
                col = label.text()
                self.merge_cols.append(col)
            self.hide_merge_cols()
            self.create_merge_plt()
        
        print(self.merge_cols)
    

    def hide_merge_cols(self):
        if self.merge_cols:
            for graph in self.graph_list:
                if graph.name in self.merge_cols:
                    graph.setVisible(False)
    
    def create_merge_plt(self):
        label_name = ",".join(self.merge_cols)
        idx = len(self.ax_list)
        
        #self.ax = pg.AxisItem('left',pen=(150,150,150),name='merge',textPen=(150,150,150))
        self.ax = self.qcp_rect.addAxis(QCPAxis.atLeft)
        self.ax.setLayer("axes")
        self.ax.setLabel(label_name)
        self.ax.setTickLength(0,6)
        self.ax.setSubTickLength(0,3)
        print(dir(QCPLineEnding))
        self.ax.setUpperEnding(QCPLineEnding(QCPLineEnding.esNone))
        self.ax.setLowerEnding(QCPLineEnding(QCPLineEnding.esNone))
        self.ax.grid().setVisible(True)
        self.ax.grid().setLayer("grid")
        self.ax.grid().setSubGridVisible(True)
        self.ax.grid().setSubGridPen(QPen(QColor("#003000"),1,Qt.PenStyle.DashLine))
        self.ax.grid().setZeroLinePen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))
        
        color = "#ffffff"
        self.set_axis_color(self.ax,color)
        print(self.ax)
        
        #self.graph_selection_changed(self.graph,None,None)
        
        for col in self.merge_cols:
            color = self.color_map.get(col,get_color())
            xdata = self.total_data[self.x_col]
            ydata = self.total_data[col]
            self.graph = self.line_plot.addGraph(self.x_axis,self.ax)
            self.graph.setAntialiased(False)
            self.graph.name = col+ "_merge"
            self.graph.setPen(QPen(QColor(color)))
            if self.line_style == 'line':
                self.graph.setPen(QPen(QColor(color)))
            if self.line_style == 'scatter':
                self.graph.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle,2))
            if self.line_style == 'ls':
                self.graph.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle,2))
            

            self.graph.setData(xdata,ydata)
            #self.tracer.setGraph(self.graph)
            #self.graph.valueAxis().setRange(ydata.min() - ydata.max() *0.05, ydata.max() + ydata.min() * 0.05)
            self.graph.rescaleAxes(True)
            self.plt_color_list.append(color)
            self.graph_list.append(self.graph)
            
            
            self.x_axis.setLabel(self.x_col)


            self.plt_gph_map[self.graph] = self.ax
            

            self.graph_list.append(self.graph)
            self.graph_selection_changed(self.graph,None,None)
            self.plt_color_list.append(color)

        self.ax_list.append(self.ax)

        self.line_plot.replot()



        

        

    

    def set_line_style(self,line_type):
        if line_type == 'line':
            for i in range(len(self.graph_list)):
                self.graph_list[i].setLineStyle(QCPGraph.lsLine)
                self.graph_list[i].setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssNone,3))

        elif line_type == 'scatter':
            for i in range(len(self.graph_list)):
                self.graph_list[i].setLineStyle(QCPGraph.lsNone)
                self.graph_list[i].setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssDisc,3))
        else:
            for i in range(len(self.graph_list)):
                self.graph_list[i].setLineStyle(QCPGraph.lsLine)
                self.graph_list[i].setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssDisc,3))

        self.line_plot.replot()

    def vb_ax_init(self,idx,xdata_name,ydata,color,name):
        if xdata_name == 'index':
            xdata = self.zdata.index
        else:
            xdata = self.zdata[xdata_name]
        print("=====================idx========================",idx)

        

        if xdata_name == 'abstimestamps':
            self.x_axis.format = 'datetime'
            dateTimeTicker = QCPAxisTickerDateTime()
            dateTimeTicker.setDateTimeFormat("yyyy-MM-dd hh:mm:ss")
            self.x_axis.setTicker(dateTimeTicker)
        else:
            self.x_axis.format = "number"


        for i,ax in enumerate(self.ax_list):
            self.ax_list[i].setVisible(False)


        if idx == 0:
            self.ax = self.qcp_rect.axis(QCPAxis.atLeft,0)
        else:
            self.ax = self.qcp_rect.addAxis(QCPAxis.atLeft)
            self.ax.setLayer("axes")
            self.ax.setTickLength(0,6)
            self.ax.setSubTickLength(0,3)

        self.ax.setLabel(name)

        self.ax.setUpperEnding(QCPLineEnding(QCPLineEnding.esNone))
        self.ax.setLowerEnding(QCPLineEnding(QCPLineEnding.esNone))
        self.ax.grid().setVisible(True)
        self.ax.grid().setLayer("grid")
        self.ax.grid().setSubGridVisible(True)
        self.ax.grid().setPen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))
        self.ax.grid().setSubGridPen(QPen(QColor("#003000"),1,Qt.PenStyle.DashLine))
        self.ax.grid().setZeroLinePen(QPen(QColor("#008000"),1,Qt.PenStyle.DashLine))
        self.set_axis_color(self.ax,color)

        self.graph = self.line_plot.addGraph(self.x_axis,self.ax)
        self.graph.setAntialiased(False)
        self.graph.name = name
        self.graph.setPen(QPen(QColor(color)))
        if self.line_style == 'line':
            self.graph.setLineStyle(QCPGraph.lsLine)
            self.graph.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssNone,3))
        if self.line_style == 'scatter':
            self.graph.setLineStyle(QCPGraph.lsNone)
            self.graph.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssDisc,3))
        if self.line_style == 'ls':
            self.graph.setLineStyle(QCPGraph.lsLine)
            self.graph.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssDisc,3))
        

        self.graph.setData(xdata,ydata)
        #self.tracer.setGraph(self.graph)
        self.graph.valueAxis().setRange(ydata.min() - ydata.max() *0.05, ydata.max() + ydata.min() * 0.05)
        self.graph.keyAxis().setRange(xdata.min(), xdata.max())
        self.graph.rescaleAxes(True)
        self.graph.rescaleKeyAxis(True)
        self.plt_color_list.append(color)
        self.graph_list.append(self.graph)
        
        self.ax_list.append(self.ax)
        self.x_axis.setLabel(xdata_name)


        self.plt_gph_map[self.graph] = self.ax
        self.graph_selection_changed(self.graph,None,None)
        self.line_plot.replot()




    def _my_line(self, var=True):
        # var 为True时,为横线,否则为竖线
        line = QFrame(self)
        line_var = QFrame.HLine
        sp_var = Qt.Horizontal
        if not var:
            line_var = QFrame.VLine
            sp_var = Qt.Vertical
        line.setFrameShape(line_var)
        line.setFrameShadow(QFrame.Sunken)
        splitter = QSplitter(sp_var)
        splitter.addWidget(line)
        return splitter



if __name__ == '__main__':
    multiprocessing.freeze_support() 
    #cgitb.enable(format="text")
    app = QApplication(sys.argv)
    #apply_stylesheet(app, theme='light_blue.xml')
    #qssfile = "./style/qss/flatgray.css"
    #qssstyle = read_qss(qssfile)
    #app.setStyleSheet(qssstyle)

    splash = QSplashScreen()
    #初始图片
    splash.setPixmap(QPixmap('数据分析.png'))  # 设置背景图片
    #初始文本
    splash.showMessage("加载... 0%", QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
    # 设置字体
    splash.setFont(QFont('微软雅黑', 10))
    # 显示启动界面
    splash.show()
    app.processEvents()  # 处理主进程事件
    #主窗口

    #window.load_data(splash)  # 加载数据


    win = MainWindow(sys.argv)
    splash.finish(win)
    splash.deleteLater()
    sys.exit(app.exec_())

Supongo que te gusta

Origin blog.csdn.net/zy1620454507/article/details/127864912
Recomendado
Clasificación