在 PyQtGraph 和 PySide2 中使用 ImageView 修复文本位置

Posted

技术标签:

【中文标题】在 PyQtGraph 和 PySide2 中使用 ImageView 修复文本位置【英文标题】:Fixed text position using an ImageView within PyQtGraph & PySide2 【发布时间】:2021-05-25 09:38:30 【问题描述】:

我正在使用 PyQtGraph 和 PySide2 显示平面 2D 图像和 3D 体积的 2D 切片(CT/MRI 体积数据集等),用户可以在其中平移/缩放、滚动等。

我想做的是在视图中的几个位置放置文本,覆盖图像,例如在角落——我可以指定的地方。 无论图像平移/缩放等如何,我都希望此文本保持其屏幕位置。 我还想在用户进行查看更改时实时更新其中的一些文本(例如查看像素大小等参数)

据我所知,最合适的选项是 LegendItem。有问题-

如何禁用用户拖动? 如何控制文本位置? .setPos() 方法无效。 如何删除/隐藏图例文本左侧的行?

替代方法是 LabelItem 或 TextItem,尽管我找不到分配 screen 位置而不是 image 位置的方法。即 - 我如何指定 view window 的左下角 而不是 image 的左下角 - 因为当然,图像可以移动。

-有没有办法固定标签/文本相对于视口的位置?

有趣的是,LabelItem 随图像平移和缩放,而 TextItem 仅随图像平移。

这是我的最低工作代码,其中包含每个文本内容的示例。

from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWidgets import QWidget
from PySide2.QtWidgets import QHBoxLayout

import pyqtgraph as pg
import numpy as np
import sys


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.cw = QWidget(self)
        self.cw.setAutoFillBackground(True)
        self.setCentralWidget(self.cw)

        self.layout = QHBoxLayout()
        self.cw.setLayout(self.layout)

        self.DcmImgWidget = MyImageWidget(parent=self)
        self.layout.addWidget(self.DcmImgWidget)

        self.show()


class MyImageWidget(pg.ImageView):
    def __init__(self, parent):
        super().__init__(parent, view=pg.PlotItem())

        self.ui.histogram.hide()
        self.ui.roiBtn.hide()
        self.ui.menuBtn.hide()

        plot_view = self.getView()
        plot_view.hideAxis('left')
        plot_view.hideAxis('bottom')

        # 50 frames of 100x100 random noise
        img = np.random.normal(size=(50, 100, 100))
        self.setImage(img)

        text0 = pg.LabelItem("this is a LabelItem", color=(128, 0, 0))
        text0.setPos(25, 25)  # <---- These are coords within the IMAGE
        plot_view.addItem(text0)

        text1 = pg.TextItem(text='This is a TextItem', color=(0, 128, 0))
        plot_view.addItem(text1)
        text1.setPos(75, -20)  # <---- These are coords within the IMAGE

        legend = plot_view.addLegend()
        style = pg.PlotDataItem(pen='w')
        legend.addItem(style, 'legend')


def main():
    app = QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

【问题讨论】:

【参考方案1】:

一种可能的解决方案是在 ImageView 使用的 QGraphicsView 的视口中添加一个 QLabel:

class MyImageWidget(pg.ImageView):
    def __init__(self, parent):
        super().__init__(parent, view=pg.PlotItem())

        self.ui.histogram.hide()
        self.ui.roiBtn.hide()
        self.ui.menuBtn.hide()

        plot_view = self.getView()
        plot_view.hideAxis("left")
        plot_view.hideAxis("bottom")

        # 50 frames of 100x100 random noise
        img = np.random.normal(size=(50, 100, 100))
        self.setImage(img)

        label = QLabel("this is a QLabel", self.ui.graphicsView.viewport())
        label.move(25, 25)

【讨论】:

再次感谢 eyllanesc!您的解决方案很好地避开了 pyqtgraph 方面。在 resizeEvent 中更新 label.move() 方法也可以很好地更新相对于角的位置。

以上是关于在 PyQtGraph 和 PySide2 中使用 ImageView 修复文本位置的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyside2 将 pyqtgraph 图添加到 QTDesigner

将 Pyqtgraph 嵌入到 PySide2

带有 PySide 2 和 QtDesigner 的 pyqtgraph

PySide2 中的 QGraphicsItem.itemClipsChildrenToShape 问题

带有 Pyside2 和 Matplotlib 的 Pyinstaller 无法正常工作

❤️GUI可视化利器,让实时数据可视化so easy