如何向pyqt5图形添加十字线

2024-10-01 17:40:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要添加一个十字线,就像页面上的这里一样。crosshair 十字线应该在鼠标后面移动。 互联网上很少有关于这个话题的例子。 到处都是“pyqtgraph”,我不懂。 我想使用按钮添加和删除十字线。 我能用一个pyqt吗

Сa使用此代码作为添加十字线的基础

from PyQt5 import QtCore, QtGui, QtWidgets, QtChart
from PyQt5.QtCore import *
from PyQt5.QtChart import *
import math
import numpy as np

mas =[1.33, 1.15, 1.55, 1.65, 1.64, 1.91, 1.33, 2.3, 1.5, 1.35, 2.52, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1,
              1.33, 1.15, 1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77, 1.7, 1.87, 2.7, 1.55, 1.73, 2.1,
              1.33, 1.15, 1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1]
x = len(mas)
x_ = x - 1

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, start = 1, parent=None):
        self.start = start
        super().__init__(parent)

        self.step = 30
        self._chart_view = QtChart.QChartView()
        self.scrollbar = QtWidgets.QScrollBar(
            QtCore.Qt.Horizontal,
            sliderMoved=self.onAxisSliderMoved,
            pageStep=self.step,
        )

        self.scrollbar.setRange(0, x_)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)

        lay = QtWidgets.QVBoxLayout(central_widget)
        for w in (self._chart_view, self.scrollbar):
            lay.addWidget(w)

        self._chart = QtChart.QChart()
        self._line_serie = QtChart.QLineSeries()

        for i in range(0, len(mas)):
            self._line_serie.append(QtCore.QPointF(i, mas[i]))

        min_x, max_x = 0, x_
        self._chart.addSeries(self._line_serie)

        axisX = QValueAxis()
        axisX.setTickCount(5)
        axisX.setLabelFormat("%d")
        self._chart.addAxis(axisX, Qt.AlignBottom)
        self._line_serie.attachAxis(axisX)

        axisY = QValueAxis()
        self._chart.addAxis(axisY, Qt.AlignLeft)
        self._line_serie.attachAxis(axisY)

        self._chart.legend().hide()
        self._chart_view.setChart(self._chart)
        self.lims = np.array([min_x, max_x])
        self.onAxisSliderMoved(self.scrollbar.value())

        self.adjust_axes(self.start, 31)

    def adjust_axes(self, value_min, value_max):
        if value_min >= 0 and value_max >= 0 and value_max <= x_ and value_max > value_min:
            self._chart.axisX(self._line_serie).setRange(value_min, value_max)

    @QtCore.pyqtSlot(int)
    def onAxisSliderMoved(self, value):
        value2 = value + self.step
        value1 = value
        if value2 >= x_:
            value2 = x_
            value1 = value2 - self.step
        self.adjust_axes(math.floor(value1), math.ceil(value2))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow(start = 0)
    w.show()
    sys.exit(app.exec_())

Tags: importselfvaluelinechartminstartmax
1条回答
网友
1楼 · 发布于 2024-10-01 17:40:47

一种可能的解决方案是重写QChartView的drawForeground方法,其中应根据鼠标位置绘制线:

class ChartView(QtChart.QChartView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._value_pos = QtCore.QPoint()
        self.setMouseTracking(True)

    def drawForeground(self, painter, rect):
        super().drawForeground(painter, rect)
        if self.chart() is None or self._value_pos.isNull():
            return

        pen = QtGui.QPen(QtGui.QColor("salmon"))
        pen.setWidth(8)
        painter.setPen(pen)

        area = self.chart().plotArea()
        sp = self.chart().mapToPosition(self._value_pos)
        x1 = QtCore.QPointF(area.left() + pen.width() / 2, sp.y())
        x2 = QtCore.QPointF(area.right() - pen.width() / 2, sp.y())
        y1 = QtCore.QPointF(sp.x(), area.top() + pen.width() / 2)
        y2 = QtCore.QPointF(sp.x(), area.bottom() - pen.width() / 2)

        if area.left() <= sp.x() <= area.right():
            painter.drawLine(y1, y2)
        if area.top() < sp.y() < area.bottom():
            painter.drawLine(x1, x2)

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        if self.chart() is None:
            return
        sp = self.mapToScene(event.pos())
        if self.chart().plotArea().contains(sp):
            self._value_pos = self.chart().mapToValue(sp)
            self.setCursor(QtCore.Qt.PointingHandCursor)
        else:
            self.unsetCursor()
        self.update()


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, start=1, parent=None):
        super().__init__(parent)
        self.start = start
        self._chart_view = ChartView()
        # ...

enter image description here

相关问题 更多 >

    热门问题