问题描述
我目前正在为 pyside 苦苦挣扎。我想制作一个几乎没有特征的图表:
- 光标所在的垂直线。就像谷歌显示股票一样
- 带有光标所在位置的标签
- 单击/双击让用户选择点
我实现的问题是垂直线/光标非常缓慢和滞后。
这是我现在所做的:
和代码
# 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)