Рисование и отображение объектов и надписей над осью в 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 системы координат.
Кто-нибудь может предложить лучший способ сделать это или как выровнять стрелки в демо с точными значениями?
Снимок экрана и код:
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_())