Рисование и отображение объектов и надписей над осью в pyqtgraph - как это сделать эффективно?

Я пытаюсь отобразить графические объекты QT поверх AxisItems в pyqtgraph.

Чтобы понять, как это сделать, потребовалось немало усилий, и я думаю, что, возможно, есть лучший способ, который более эффективно использует встроенные функции pyqtgraph mapToScene / mapToView.

Сначала я думал, что это будет легко, и из документации ( http://www.pyqtgraph.org/documentation/plotting.html) это будет просто случай рисования объекта и ссылки на Координаты pyqtgraph в PlotItem(GraphicsItem) с более высоким значением Z должны заставить объекты плавать поверх AxisItems.

Однако, когда я пытаюсь это сделать, они исчезают за Осью, независимо от того, насколько высоко я установил значение Z или какой-либо объект (viewbox/plotitem/plotwidget), который я выбрал в качестве родителя. В качестве обходного пути я вместо этого ссылаюсь на QTGraphicsScene, и он работает, но координаты немного отклоняются на пару пикселей, как вы можете видеть из моего демонстрационного кода, когда мышь перемещается, что и следовало ожидать, поскольку она переводит между pyqtgraph и Qt системы координат.

Кто-нибудь может предложить лучший способ сделать это или как выровнять стрелки в демо с точными значениями?

от: http://www.pyqtgraph.org/documentation/plotting.html#organization-of-plotting-classes

Снимок экрана и код:

Перекрестие со стрелками на оси

from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication, QLabel, QMainWindow, QHBoxLayout, QVBoxLayout
from PyQt5.QtCore import QThread
from PyQt5.QtCore import QObject
from PyQt5.QtCore import pyqtSlot, pyqtSignal

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
from mainwindowgraph import Ui_MainWindow as QTestGraphMainWindow 
import sys

class TestGraphWidget(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):               
        self.ui = QTestGraphMainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle('Test Graphwindow')
        #This line is required to get the corect  viewbox
        self.vb = self.ui.mainplot.plotItem.vb

        proxy = pg.SignalProxy(self.ui.mainplot.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
        self.ui.mainplot.scene().sigMouseMoved.connect(self.mouseMoved)

        #cross hair
        self.vLine = pg.InfiniteLine(angle=90, movable=False)
        self.hLine = pg.InfiniteLine(angle=0, movable=False)
        self.vLine.setZValue(2)
        self.hLine.setZValue(2)
        self.ui.mainplot.addItem(self.vLine, ignoreBounds=True)
        self.ui.mainplot.addItem(self.hLine, ignoreBounds=True)
        self.h_arrow = pg.ArrowItem(angle=0)
        self.v_arrow = pg.ArrowItem(angle=90)

        self.ui.mainplot.scene().addItem(self.v_arrow)
        self.ui.mainplot.scene().addItem(self.h_arrow)

        self.h_arrow.setZValue(10)
        self.v_arrow.setZValue(10)
        self.ui.mainplot.addItem(pg.PlotCurveItem([99,20,40,31,40,1], pen='b'))

    def mouseMoved(self, evt):
        pos = evt
        if self.ui.mainplot.sceneBoundingRect().contains(pos):
            mousePoint = self.vb.mapSceneToView(pos)
            #TODO - link  to axisitem instead of plotItemvb  <ViewBox>
            axis_offset = 0
            rightaxis_x = self.ui.mainplot.plotItem.vb.x() + self.ui.mainplot.plotItem.vb.width() + axis_offset 
            bottomaxis_y = self.ui.mainplot.plotItem.vb.y() + self.ui.mainplot.plotItem.vb.height() + axis_offset 
            index_x = mousePoint.x()
            print('x= {}, y = {}'.format(mousePoint.x() , mousePoint.y()))
            self.vLine.setPos(index_x)
            self.hLine.setPos(mousePoint.y())
            self.h_arrow.setPos(rightaxis_x, pos.y())
            self.v_arrow.setPos(pos.x(), bottomaxis_y)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    testgraphwindow = TestGraphWidget()
    testgraphwindow.ui.mainplot.showAxis('right')
    testgraphwindow.ui.mainplot.hideAxis('left')
    testgraphwindow.show()
    sys.exit(app.exec_())

mainwindowgraph.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file ''
#
# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(921, 545)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.graphbuttons_horizontalLayout = QtWidgets.QHBoxLayout()
        self.graphbuttons_horizontalLayout.setObjectName("graphbuttons_horizontalLayout")
        spacerItem = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        self.graphbuttons_horizontalLayout.addItem(spacerItem)
        spacerItem1 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        self.graphbuttons_horizontalLayout.addItem(spacerItem1)


        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.graphbuttons_horizontalLayout.addItem(spacerItem2)
        spacerItem3 = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        self.graphbuttons_horizontalLayout.addItem(spacerItem3)
        self.verticalLayout.addLayout(self.graphbuttons_horizontalLayout)
        self.mainplot = PlotWidget(self.centralwidget)
        self.mainplot.setObjectName("mainplot")
        self.verticalLayout.addWidget(self.mainplot)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 921, 22))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionClose = QtWidgets.QAction(MainWindow)
        self.actionClose.setObjectName("actionClose")


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.actionClose.setText(_translate("MainWindow", "Close"))

from pyqtgraph import PlotWidget

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

0 ответов

Другие вопросы по тегам