如何用鼠标在QChart中移动系列?

时间:2018-02-08 02:58:47

标签: python pyqt coordinates mouse qchart

我已经用PyQtChart画了一张图表,我想用鼠标移动一个系列。按右键选择一个系列,然后将其移动到目标位置,释放右键后将系列放到目标位置。 我可以在update_select_series中获取所选系列,如果我可以在按下右键和目标坐标时获得原始坐标,因此我可以将系列移动到update_series中的目标位置,但我不会知道如何实现它。

import sys
from PyQt5.QtChart import QAreaSeries, QChart, QChartView, QLineSeries, QValueAxis, QCategoryAxis
from PyQt5.QtCore import QPointF, Qt, QTimer
from PyQt5.QtGui import QColor, QGradient, QLinearGradient, QPainter, QPen
from PyQt5.QtWidgets import QApplication, QMainWindow

app = QApplication(sys.argv)

series0 = QLineSeries()

series0 << QPointF(1, 15) << QPointF(3, 17) << QPointF(7, 16) << QPointF(9, 17) \
        << QPointF(12, 16) << QPointF(16, 17) << QPointF(18, 15)

chart = QChart()
chart.addSeries(series0)
chart.createDefaultAxes()
chartView = QChartView(chart)

def update_select_series():
    print('update_select_series')

def update_series():
    print('update_series')

series0.pressed.connect(update_select_series)
series0.released.connect(update_series)

window = QMainWindow()
window.setCentralWidget(chartView)
window.resize(400, 300)
window.show()

sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:0)

pressed信号包含按下的点的信息,released信号也是如此,也就是说,两个点都相同,所以释放的信号只会告诉我们什么时候鼠标被释放了,但不是在哪里。

要解决此问题,您必须获取释放鼠标的以下点,为此您可以使用事件mouseReleaseEvent,这将返回QGraphicsView坐标点,然后我们必须更改它到图的坐标,所以我们可以使用这个response

然后你必须传输给它的系列,你可以创建一个自定义事件并通过postEvent()发送,在系列中,方法customEvent()用于获取端点的信息。

要移动系列,您将获得点并添加位移,并且必须再次插入。

import sys
from PyQt5.QtChart import QChart, QChartView, QLineSeries
from PyQt5.QtCore import QPointF, QEvent
from PyQt5.QtWidgets import QApplication, QMainWindow

class ReleasePosEvent(QEvent):  
    EventType = QEvent.Type(QEvent.registerEventType())
    def __init__(self, point):
        QEvent.__init__(self, ReleasePosEvent.EventType)
        self.point = point


class ChartView(QChartView):
    def mouseReleaseEvent(self, event):
        p1 = event.pos()
        p2 = self.mapToScene(p1)
        p3 = self.chart().mapFromScene(p2)
        p4 = self.chart().mapToValue(p3)
        if self.chart():
            for serie in self.chart().series():
                QApplication.postEvent(serie, ReleasePosEvent(p4))
        QChartView.mouseReleaseEvent(self, event)


class LineSeries(QLineSeries):
    def __init__(self, *args, **kwargs):
        QLineSeries.__init__(self, *args, **kwargs)
        self.start = QPointF()
        self.pressed.connect(self.on_pressed)

    def on_pressed(self, point):
        self.start = point
        print("on_pressed", point)

    def shift(self, delta):
        if not delta.isNull():
            for ix in range(self.count()):
                p = self.at(ix)
                p += delta
                self.replace(ix, p)

    def customEvent(self, event):
        if event.type() == ReleasePosEvent.EventType:
            if not self.start.isNull():
                dpoint = event.point - self.start
                self.shift(dpoint)
                self.start = QPointF()

app = QApplication(sys.argv)
series0 = LineSeries()

series0 << QPointF(1, 15) << QPointF(3, 17) << QPointF(7, 16) << QPointF(9, 17) \
        << QPointF(12, 16) << QPointF(16, 17) << QPointF(18, 15)

chart = QChart()
chart.addSeries(series0)
chart.createDefaultAxes()
chartView = ChartView(chart)

window = QMainWindow()
window.setCentralWidget(chartView)
window.resize(400, 300)
window.show()

sys.exit(app.exec_())