问题描述
你好Pyqtgraph社区,
我希望能够在PyQtGraph中生成的3D交互式绘图中创建“固定”文本窗口。 该文本窗口将包含与仿真有关的信息,并且无论您放大/缩小还是向左或向右平移,该窗口始终始终可见。并且窗口的位置不应更改。
到目前为止,我找到的所有解决方案均创建一个文本对象,该对象随轴的缩放比例变化而移动。例如,下面的代码在3D轴上打印文本,但是一旦放大/缩小,文本就会在整个位置移动。任何想法将不胜感激。
预先感谢
from pyqtgraph.Qt import QtCore,QtGui
import pyqtgraph.opengl as gl
from pyqtgraph.opengl.GLGraphicsItem import GLGraphicsItem
class GLTextItem(GLGraphicsItem):
"""
Class for plotting text on a GLWidget
"""
def __init__(self,X=None,Y=None,Z=None,text=None):
GLGraphicsItem.__init__(self)
self.setGLOptions('translucent')
self.text = text
self.X = X
self.Y = Y
self.Z = Z
def setGLViewWidget(self,GLViewWidget):
self.GLViewWidget = GLViewWidget
def setText(self,text):
self.text = text
self.update()
def setX(self,X):
self.X = X
self.update()
def setY(self,Y):
self.Y = Y
self.update()
def setZ(self,Z):
self.Z = Z
self.update()
def paint(self):
self.GLViewWidget.qglColor(QtCore.Qt.white)
self.GLViewWidget.renderText(self.X,self.Y,self.Z,self.text)
if __name__ == '__main__':
# Create app
app = QtGui.QApplication([])
w1 = gl.GLViewWidget()
w1.resize(800,800)
w1.show()
w1.setwindowTitle('Earth 3D')
gl_txt = GLTextItem(10,10,'Sample test')
gl_txt.setGLViewWidget(w1)
w1.addItem(gl_txt)
while w1.isVisible():
app.processEvents()
解决方法
所以我终于找到了解决方案。需要做的是:
- 继承 GLViewWidget
- 从派生类中重载paintGL(),以便每次调用paigGL() 时,它都使用成员函数renderText() 在屏幕上渲染文本。
renderText() 被重载以支持绝对屏幕坐标以及基于轴的坐标: i) renderText(int x,int y,const QString &str,const QFont &font = QFont()): 基于 (x,y) 窗口坐标绘制 ii) renderText(double x,double y,double z,const QFont &font = QFont()): 在 (x,y,z) 场景坐标上绘图
您可能想要使用 QtGui.QFontMetrics() 类来获取渲染文本的尺寸,以便将其放置在对您的应用程序有意义的位置,如下面的代码所示。
from pyqtgraph.opengl import GLViewWidget
import pyqtgraph.opengl as gl
from PyQt5.QtGui import QColor
from pyqtgraph.Qt import QtCore,QtGui
class GLView(GLViewWidget):
"""
I have implemented my own GLViewWidget
"""
def __init__(self,parent=None):
super().__init__(parent)
def paintGL(self,*args,**kwds):
# Call parent's paintGL()
GLViewWidget.paintGL(self,**kwds)
# select font
font = QtGui.QFont()
font.setFamily("Tahoma")
font.setPixelSize(21)
font.setBold(True)
title_str = 'Screen Coordinates'
metrics = QtGui.QFontMetrics(font)
m = metrics.boundingRect(title_str)
width = m.width()
height = m.height()
# Get window dimensions to center text
scrn_sz_width = self.size().width()
scrn_sz_height = self.size().height()
# Render text with screen based coordinates
self.qglColor(QColor(255,255,255))
self.renderText((scrn_sz_width-width)/2,height+5,title_str,font)
# Render text using Axis-based coordinates
self.qglColor(QColor(255,255))
self.renderText(0,'Axis-Based Coordinates')
if __name__ == '__main__':
# Create app
app = QtGui.QApplication([])
w = GLView()
w.resize(800,800)
w.show()
w.setWindowTitle('Earth 3D')
w.setCameraPosition(distance=20)
g = gl.GLGridItem()
w.addItem(g)
while w.isVisible():
app.processEvents()