解析ツール QCustomPlot2 バージョン

        今週は、主に pyqtgraph から QCustomPlot2 への描画コントロールの移行を実現しました. 全体的な感じとしては、まず第一に、この描画コントロールは偉大なマスターの手によるものであり、品質はもちろんそうではありません. 「cpp の qt エコロジーは非常に人気があります。なぜなら、私はインターネットで python しか見つけられなかったからです。そうです、他はすべて cpp のバージョン コードです。python を使用する人はほとんどいませんが、偉大な神の輝きを隠すことはできません。.今週の移行プロセスのいくつかのバンプ, 最終的に, 以前にpyqtgraphに実装されたすべての機能が正常に実装されました. それはplot2に実装されました. 私は、このコントロールを使用して同じ機能を達成すると言わなければなりません, 実装コードはそうではありません減少しただけですが、問題はほとんどありません. 明らかなバグがあるpyqtgraphとは異なり、コントロール自体に基本的にバグは見つかりませんでした (もちろん、それは私の食べ物でもあるかもしれません) 同時に、pyqtgraphに現れたパフォーマンスの問題pyqtgraph で散布図を描くと、データが多すぎると非常に固まるのですが、折れ線グラフは非常に滑らかで、何が問題なのかわかりません ( # ただし、基本的にはQCustomPlot2) で散布図と折れ線グラフを描画する際のパフォーマンスに違いはありません. 訂正させてください. このコントロールの散布図もデータ量が多い場合, 特にトレーサーが移動する場合に問題があります. pyqtgraph と同じはずです. . openglにしか期待できないようですが、openglサポートを自分でコンパイルするのは少し面倒です. 後で見てみましょう, しかし、機能はまだかなり完璧です.

言うことはあまりありませんが、コードを入れてください:

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_())

Guess you like

Origin blog.csdn.net/zy1620454507/article/details/127864912