我试图在pyqtgraph的AxisItems顶部显示QT的图形对象。
花了很多时间才弄清楚如何做到这一点,我认为也许有更好的方法可以更有效地使用内置pyqtgraph mapToScene / mapToView函数。
我最初认为这很容易,并且从文档(http://www.pyqtgraph.org/documentation/plotting.html#organization-of-plotting-classes)开始,只是绘制对象并引用Z值较高的PlotItem(GraphicsItem)中的pyqtgraph坐标的情况使对象浮动在AxisItems的顶部。
但是,无论我将Z值设置为多高还是我选择作为父对象的任何对象(视图框/图形/图形控件),它们都会在Axis后面消失。作为一种解决方法,我引用了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_())