简体   繁体   中英

Pyqtgraph mouse crosshair

I want a mouse crosshair for a pyqtgraph (GraphicsView()). I was able to create a crosshair in a separate window using the code at the following link: pyqtgraph: add crosshair on mouse_x graph_y , but I can't re-create It in GraphicsView(). This Is my current code, but It Isn't working:

import sys
import pyqtgraph as pg
from PyQt6 import QtCore
from PyQt6.QtWidgets import *


class CrosshairPlotWidget(QWidget):
    """Scrolling plot with crosshair"""

    def __init__(self, parent=None):
        super(CrosshairPlotWidget, self).__init__(parent)

        self.LEFT_X = -10
        self.RIGHT_X = 0

        self.crosshair_plot_widget = pg.PlotWidget()
        # self.crosshair_plot_widget.setXRange(self.LEFT_X, self.RIGHT_X)
        self.crosshair_plot_widget.setLabel('left', 'Price')
        self.crosshair_plot_widget.setLabel('bottom', 'Time')
        self.crosshair_color = (196, 220, 255)

        self.crosshair_plot = self.crosshair_plot_widget.plot()

        self.layout = QGridLayout()
        self.layout.addWidget(self.crosshair_plot_widget)

        self.crosshair_plot_widget.plotItem.setAutoVisible(y=True)
        self.vertical_line = pg.InfiniteLine(angle=90)
        self.horizontal_line = pg.InfiniteLine(angle=0, movable=False)
        self.vertical_line.setPen(self.crosshair_color)
        self.horizontal_line.setPen(self.crosshair_color)
        self.crosshair_plot_widget.setAutoVisible(y=True)
        self.crosshair_plot_widget.addItem(self.vertical_line, ignoreBounds=True)
        self.crosshair_plot_widget.addItem(self.horizontal_line, ignoreBounds=True)

        self.crosshair_update = pg.SignalProxy(self.crosshair_plot_widget.scene().sigMouseMoved, rateLimit=60, slot=self.update_crosshair)

    def update_crosshair(self, event):
        """Paint crosshair on mouse"""

        coordinates = event[0]
        if self.crosshair_plot_widget.sceneBoundingRect().contains(coordinates):
            mouse_point = self.crosshair_plot_widget.plotItem.vb.mapSceneToView(coordinates)
            index = mouse_point.x()
            if self.LEFT_X < index <= self.RIGHT_X:
                self.crosshair_plot_widget.setTitle("<span style='font-size: 12pt'>x=%0.1f,   <span style='color: red'>y=%0.1f</span>" % (mouse_point.x(), mouse_point.y()))
            self.vertical_line.setPos(mouse_point.x())
            self.horizontal_line.setPos(mouse_point.y())

    def get_crosshair_plot_layout(self):
        return self.layout

# Create crosshair plot
crosshair_plot = CrosshairPlotWidget()

app = QApplication(sys.argv)
view = pg.GraphicsView()
l = pg.GraphicsLayout()
view.setCentralItem(l)
view.show()

# cw = QWidget()
# ml = QGridLayout()
# cw.setLayout(ml)
# view.setCentralWidget(cw)

l.addLayout(crosshair_plot.get_crosshair_plot_layout(), 0, 0)

if __name__ == '__main__':
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QApplication.instance().exec()

Any ideas of how I can do that?

Get the mouse position in the viewport, convert the viewport position to scene coordinates, convert the scene coordinates to plot coordinates, update the position of the vertical and horizontal lines:

def update_crosshair(self, event):
    view_pos = self.crosshair_plot_widget.mapFromGlobal(QCursor.pos())
    scene_pos = self.crosshair_plot_widget.viewport().mapToScene(view_pos)
    plot_pos = self.crosshair_plot_widget.plotItem.vb.mapSceneToView(scene_pos)
    self.vertical_line.setPos(plot_pos.x())
    self.horizontal_line.setPos(plot_pos.y())

Let me know if it helped!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM