2

我用 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_())
4

1 回答 1

2

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

要解决此问题,您必须获取鼠标释放的以下点,为此您可以使用事件mouseReleaseEvent,这将返回坐标中的点QGraphicsView,然后我们必须将其更改为绘图的坐标,以便我们可以使用此响应

然后您必须为它传输到系列,您可以创建一个自定义事件并通过它发送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_())
于 2018-02-08T05:51:52.900 回答