快速更新垂直线位置

问题描述

我目前正在为 pyside 苦苦挣扎。我想制作一个几乎没有特征的图表:

  1. 光标所在的垂直线。就像谷歌显示股票一样
  2. 带有光标所在位置的标签
  3. 单击/双击让用户选择点

I would like to have a vertical line and possibly a label

我实现的问题是垂直线/光标非常缓慢和滞后。

这是我现在所做的:

enter image description here

和代码

# This Python file uses the following encoding: utf-8
import sys,os
from random import randint
from PySide2 import QtCore,QtGui
from PySide2.QtWidgets import *
from PySide2.QtCharts import *
from PySide2.QtGui import QPainter,QKeySequence,QColor
from PySide2.QtCore import Qt,QPointF,QPoint,Signal
from enum import Enum
from numpy import math


class Derived(QtCharts.QChartView): # Derived class
    pen = QtGui.QPen( QColor("black"),1,QtCore.Qt.SolidLine)
    m_MousePos = QPoint(0,0)

    def drawForeground(self,painter,rect): # overriding method
        super().drawForeground(painter,rect)
        sceneRect = self.sceneRect()
        painter.setClipRect(rect)
        painter.setPen(self.pen)
        painter.drawLine(self.m_MousePos.x(),sceneRect.top(),self.m_MousePos.x(),sceneRect.bottom())


    def mouseMoveEvent(self,event):
        newMousePos = QPoint(event.x(),event.y())
        if(self.m_MousePos != newMousePos):
            self.m_MousePos = QPoint(event.x(),event.y())
            super().mouseMoveEvent(event)

class MainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)

        widget = QWidget()
        self.setCentralWidget(widget)

        self.currentFileIndex = 0
        self.Signal1Data = []
        self.Signal2Data = []
        self.selectedPoints = []

        self.chart = QtCharts.QChart()
        self.updateChart()
        self.chartView = Derived(self.chart)#QtCharts.QChartView(self.chart)#Derived(self.chart)
        self.chartView.setMouseTracking(True)

        self.chartView.setRubberBand(QtCharts.QChartView.HorizontalRubberBand)
        self.chartView.setRenderHint(QPainter.Antialiasing)
        self.loadSignalFile()

        self.removeLastButton = QPushButton(self.tr("Remove last point"))
        self.removeLastButton.clicked.connect(self.popSelectedPoint)

        layout =  QGridLayout()
        self.instructionLabel = QLabel(self.tr("Start by identifying feature (mouse click on signal)"))  
        font = QtGui.QFont( "Arial",18,QtGui.QFont.Bold)
        self.instructionLabel.setFont(font)
        layout.addWidget(self.instructionLabel,0 )

        layout.addWidget(self.chartView,2)
        layout.addWidget(self.chartView,2)
        layout.addWidget(self.removeLastButton,2,0)
        widget.setLayout(layout)

        self.statusBar().showMessage("message")

        self.setWindowTitle(self.tr("Feature Identifier"))
        self.setMinimumSize(160,160)
        self.resize(800,600)

    def updateChart(self):
        self.chart.removeAllSeries()
        self.Signal1LineSeries = QtCharts.QLineSeries()
        self.Signal2LineSeries = QtCharts.QLineSeries()
        self.Signal1LineSeries.setName("1")
        self.Signal2LineSeries.setName("2")

        pen = QtGui.QPen()
        pen.setWidth(3)
        pen.setColor(QColor("red"))
        self.Signal1LineSeries.setPen(pen)
        pen.setColor(QColor("royalblue"))
        self.Signal2LineSeries.setPen(pen)

        self.SelectedPointsSeries = QtCharts.QScatterSeries()
        self.SelectedPointsSeries.setName("Selected points")
        self.SelectedPointsSeries.setMarkerSize(10.0)
        pen.setColor(QColor("green"))
        pen.setWidth(1)
        self.SelectedPointsSeries.setPen(pen)

        dataPoints = [QtCore.QPointF(i+1,self.Signal1Data[i]) for i in range(len(self.Signal1Data))]
        self.Signal1LineSeries.replace(dataPoints)

        dataPoints = [QtCore.QPointF(i+1,self.Signal2Data[i]) for i in range(len(self.Signal2Data))]
        self.Signal2LineSeries.replace(dataPoints)

        self.Signal1LineSeries.clicked.connect(self.on_clicked1)
        self.Signal2LineSeries.clicked.connect(self.on_clicked2)
        
        self.chart.addSeries(self.Signal1LineSeries)
        self.chart.addSeries(self.Signal2LineSeries)
        self.addSelectedPoints()
        self.chart.addSeries(self.SelectedPointsSeries)
        
        self.chart.createDefaultAxes()
        self.chart.setTitle("Title")

    def verifyClick(self,series,p,threshold=2):
        xIndex = round(p.x())
        diff = p.y()- series.pointsVector()[xIndex].y()
        if abs( diff ) < threshold:
            return xIndex

    @QtCore.Slot()
    def on_clicked2(self,p):
        #check if acquiring click on signal 2
        x = self.verifyClick(self.Signal2LineSeries,p)
        if x is not None:
            print("2 clicked: ",x)
            self.recordSelectedPoint(int(x),self.Signal2LineSeries)
            self.updateChart()

    @QtCore.Slot()
    def on_clicked1(self,p):
        #check if acquiring click on Pd
        x = self.verifyClick(self.Signal1LineSeries,p)
        if x is not None:
            print("1 clicked: ",self.Signal1LineSeries)
            self.updateChart()

    def recordSelectedPoint(self,i,lineSeries):
        self.selectedPoints.append(QPointF(i,lineSeries.at(i).y()))

    def addSelectedPoints(self):
        self.SelectedPointsSeries.replace(self.selectedPoints)

    def loadSignalFile(self):
        self.Signal1Data = []
        self.Signal2Data = []

        for row in range(1200):
            self.Signal1Data.append(math.sin(row/125))
            self.Signal2Data.append(math.sin((row+25)/125))
        self.updateChart()

    @QtCore.Slot()
    def popSelectedPoint(self):
        self.selectedPoints.pop()
        self.loadSignalFile()

if __name__ == "__main__":

    app = QApplication([])
    window = MainWindow()
    window.show()


    sys.exit(app.exec_())

---编辑---

似乎光标只有在信号线上方时才会移动!我该如何纠正?

解决方法

如果你想重新绘制它,那么你必须调用 update() 或 repaint() 方法:

def mouseMoveEvent(self,event):
    newMousePos = event.pos()
    if self.m_MousePos != newMousePos:
        self.m_MousePos = newMousePos
        self.update()
    super().mouseMoveEvent(event)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...