在不缩放或移动的 3d 图中绘制文本
Posted
技术标签:
【中文标题】在不缩放或移动的 3d 图中绘制文本【英文标题】:Plot text in 3d-plot that does not scale or move 【发布时间】:2021-02-12 11:23:38 【问题描述】:你好 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, 10, 'Sample test')
gl_txt.setGLViewWidget(w1)
w1.addItem(gl_txt)
while w1.isVisible():
app.processEvents()
【问题讨论】:
【参考方案1】:所以我终于能够找到解决方案。需要做的是:
-
子类化 GLViewWidget
从派生类中重载paintGL(),以便每次调用paingGL() 时它都使用成员函数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 QString &str, 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, *args, **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,0,255))
self.renderText((scrn_sz_width-width)/2, height+5, title_str, font)
# Render text using Axis-based coordinates
self.qglColor(QColor(255, 0, 0, 255))
self.renderText(0, 0, 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()
【讨论】:
以上是关于在不缩放或移动的 3d 图中绘制文本的主要内容,如果未能解决你的问题,请参考以下文章
在不移动叠加视图的情况下裁剪和缩放图像,而是在 ImageView 中移动图像