0

我目前正在与 pyside 作斗争。我想制作一个具有几个特征的图表:

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

我想要一条垂直线,可能还有一个标签

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

这是我现在所做的:

在此处输入图像描述

和代码

# 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, 0 )

        layout.addWidget(self.chartView, 1, 0, 1, 2)
        layout.addWidget(self.chartView, 1, 0, 1, 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: ", x)
            self.recordSelectedPoint(int(x), 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_())

- -编辑 - -

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

4

1 回答 1

0

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

def mouseMoveEvent(self, event):
    newMousePos = event.pos()
    if self.m_MousePos != newMousePos:
        self.m_MousePos = newMousePos
        self.update()
    super().mouseMoveEvent(event)
于 2021-01-19T16:14:25.880 回答