将 VTK 插入布局的正确位置 [英] Insert VTK into the right spot of layout

查看:57
本文介绍了将 VTK 插入布局的正确位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 VTK 3D 场景小部件放入 pyqtgraphics.GraphicsLayout() 的正确位置.但是,如果我没有将窗口指定为父级,则场景不会出现,或者如果我这样做了 - 场景不适应自由区域,它只是漂浮在左上角.

I am trying to put the VTK 3D scene widget into the right spot of pyqtgraphics.GraphicsLayout(). But either the scene does not appear if i am not assigning the window as parent or if I do - the scene does not adapt to the free area, it is just floating in the upper left corner.

我目前正在努力寻找将视图框和 vtkrenderer 放入同一窗口的解决方案.

I am currently struggling to find a solution to put a viewbox and vtkrenderer into the same window.

我的一个尝试是分配 self.w(见本段下文)-这是我的主窗口作为渲染器的父窗口,但是我不知道如何告诉渲染器将自己放在较低的位置窗口的右上角而不是浮动在左上角 - 这也会导致窗口中其他元素的重叠.

One of my attempts was to assign the self.w (see below this paragraph)- which is my main window as a parent to the renderer but then I don't know how to tell the renderer to place itself in the lower right corner of the window instead of floating in the upper left corner - which also leads to overlapping of other elements in the window.

创建新窗口并将此窗口指定为父窗口

Creating new window and assigning this window as parent

self.vtkWidget = QVTKRenderWindowInteractor(self.w_3d)

使用引用窗口作为父窗口 -> 导致渲染场景浮动和重叠

Using refered window as parent -> leads to floating and overlapping rendered scene

self.vtkWidget = QVTKRenderWindowInteractor(self.w)

import pyqtgraph as pg
import pyqtgraph.opengl as gl
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
import vtk, sys

class GUI:
    def __init__(self):
        self.init_gui() 

    def proxyWidget(self, item, width=None, height=None):
        proxy = QtGui.QGraphicsProxyWidget()
        if(height != None):
            height = item.sizeHint().height() if height==None else height
            item.setMaximumHeight(height)
        if(width!=None):
            width = item.sizeHint().width() if width==None else width
            item.setMaximumWidth(width)
        proxy.setWidget(item)
        return proxy

    def init_gui(self, win_height=800, win_width=1800):
        #self.w = self
        #self.w.scene().sigMouseClicked.connect(self.mousePressEvent) #mouseMoveEvent
        #self.w.scene().sigMouseMoved.connect(self.mouseMoveEvent)
        pg.setConfigOptions(imageAxisOrder='row-major')
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')
        self.w = pg.GraphicsWindow(size=(win_width,win_height), border=True)
        self.img = pg.ImageItem()
        self.list_imgs       = QtGui.QListWidget()
        self.btn_Del_Mark    = QtGui.QPushButton('Del Mark')
        self.btn_MarkPed     = QtGui.QPushButton('Mark ped')
        self.lbl_list1       = QtGui.QLabel("List Images")
        self.lbl_list2       = QtGui.QLabel("List Markings")
        self.list_imgs       = QtGui.QListWidget()
        self.list_marks      = QtGui.QListWidget()
        self.layout = pg.GraphicsLayout()
        self.w_3d = pg.GraphicsWindow()
        self.vb = pg.ViewBox()


        self.lbl_list1.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_list2.setAlignment(QtCore.Qt.AlignCenter)
        self.vb.setAspectLocked()
        self.vb.addItem(self.img)
        self.vb.invertY(True)
        self.vtkWidget = QVTKRenderWindowInteractor(self.w_3d)
        self.w_3d.addItem(self.proxyWidget(self.vtkWidget))

        self.vtkWidget.Initialize()
        self.vtkWidget.Start()
        self.ren = vtk.vtkRenderer()
        self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
        self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()

        # Create source
        source = vtk.vtkSphereSource()
        source.SetCenter(0, 0, 0)
        source.SetRadius(5.0)

        # Create a mapper
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(source.GetOutputPort())

        # Create an actor
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)

        self.ren.AddActor(actor)

        self.ren.ResetCamera()
        self.iren.Initialize()
        self.iren.Start()
        self.vtkWidget.show()

        self.layout.addItem(self.vb                             , 1,  3, 20,  20)
        self.layout.addItem(self.proxyWidget(self.lbl_list1     , width=(int(1./10.*win_width)), height=(int(0.9/20.*win_height))),  0,1,1,1)   
        self.layout.addItem(self.proxyWidget(self.lbl_list2     , width=(int(1./10.*win_width)), height=(int(0.9/20.*win_height))),  0,2,1,1)  
        self.layout.addItem(self.proxyWidget(self.list_imgs     , width=(int(1./10.*win_width))),  1,1,20,1)   
        self.layout.addItem(self.proxyWidget(self.list_marks    , width=(int(1./10.*win_width))),  1,2,20,1)   

        self.w.addItem(self.layout)

if __name__ == "__main__":
    app = QtGui.QApplication([])
    guiobj = GUI()

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

目前我已经通过使用两个窗口解决了这个问题 - 经过几天的尝试失败.但即使这看起来也很糟糕 - 因为渲染的场景漂浮在窗口中而对窗口调整大小事件没有反应......

Currently I have solved it by having two windows - after several days of failed attempts. But even this looks crap - since the rendered scene floats in the window without reaction to window resize events...

我希望将这两个窗口合二为一:

I would like to have those two windows - in one:

失败的尝试之一如下 - 但随后 pyqt 获取了布局中的空间,而没有在窗口中显示渲染器场景...... - 只是空白空间:

One of the failed attempts was as follows - but then pyqt acquires space in the layout without showing the renderer scene in the window... - just empty space:

self.vtkWidget = QVTKRenderWindowInteractor() #No Parent
#...see rest of code in the section above with exception of the following 2 lines
self.layout.addItem(self.proxyWidget(self.vtkWidget), 10, 3, 10, 20)
self.vtkWidget.show()

推荐答案

我能够解决它 - 我已经用 QGridlayout 替换了 QGraphicsLayout 并删除了所有 proxywidget-wrappers,我找到了一种使用 plotwidget 添加视图框的解决方法.

I was able to solve it - I have replaced the QGraphicsLayout with QGridlayout and removed all proxywidget-wrappers and I found a workaround for adding a viewbox by using the plotwidget.

我现在只需要移除轴 - 但这是次要的

I just need now to remove the axes - but this is secondary

import pyqtgraph as pg
import pyqtgraph.opengl as gl
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
import vtk, sys
import numpy as np
from PIL import Image
class GUI:
    def __init__(self):
        self.init_gui() 

    def proxyWidget(self, item, width=None, height=None):
        proxy = QtGui.QGraphicsProxyWidget()
        if(height != None):
            height = item.sizeHint().height() if height==None else height
            item.setMaximumHeight(height)
        if(width!=None):
            width = item.sizeHint().width() if width==None else width
            item.setMaximumWidth(width)
        proxy.setWidget(item)
        return proxy

    def init_gui(self, win_height=800, win_width=1800):
        pg.setConfigOptions(imageAxisOrder='row-major')
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')
        self.w = pg.GraphicsWindow(size=(win_width,win_height), border=True)
        self.img = pg.ImageItem()
        self.list_imgs       = QtGui.QListWidget()
        self.btn_Del_Mark    = QtGui.QPushButton('Del Mark')
        self.btn_MarkPed     = QtGui.QPushButton('Mark ped')
        self.lbl_list1       = QtGui.QLabel("List Images")
        self.lbl_list2       = QtGui.QLabel("List Markings")
        self.list_imgs       = QtGui.QListWidget()
        self.list_marks      = QtGui.QListWidget()
        self.layout = QtGui.QGridLayout()
        self.w.setLayout(self.layout)
        #self.w_3d = pg.GraphicsWindow()

        self.vtkWidget = QVTKRenderWindowInteractor()
        #self.w_3d.addItem(self.proxyWidget(self.vtkWidget))

        self.vtkWidget.Initialize()
        self.vtkWidget.Start()
        self.ren = vtk.vtkRenderer()
        self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
        self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()

        # Create source
        source = vtk.vtkSphereSource()
        source.SetCenter(0, 0, 0)
        source.SetRadius(5.0)

        # Create a mapper
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(source.GetOutputPort())

        # Create an actor
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)

        self.ren.AddActor(actor)

        self.ren.ResetCamera()
        self.iren.Initialize()
        self.iren.Start()
        path = "/home/brain/uni/frustum-pointnets/dataset/KITTI/object/testing/image_2/000000.png"
        imgdata = Image.open(path)
        self.imgArr = np.array(imgdata)
        #ToDo: undistort Image if neccessary

        self.img.setImage(self.imgArr)
        #self.vbLayout = self.w.addLayout(row=0,  col=3, rowspan=10,  colspan=20)
        imageGraph = pg.PlotWidget(name='Signalgraph')
        self.vb = imageGraph.plotItem.vb
        self.lbl_list1.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_list2.setAlignment(QtCore.Qt.AlignCenter)
        self.vb.setAspectLocked()
        self.vb.addItem(self.img)
        self.vb.invertY(True)
        self.vb.setMaximumSize(int(7/10.*win_width), int(9/20.*win_height))
        self.layout.addWidget(imageGraph,                           1 , 3, 10,  20)
        self.layout.addWidget(self.vtkWidget                      , 11, 3, 10,  20)
        self.layout.addWidget(self.lbl_list1 ,                                  0, 1, 1, 1)   
        self.layout.addWidget(self.lbl_list2 ,                                  0, 2, 1, 1)  
        self.layout.addWidget(self.list_imgs ,                                  1, 1, 20,1)   
        self.layout.addWidget(self.list_marks,                                  1, 2, 20,1)   
        sizeHint =  lambda: pg.QtCore.QSize(int(1./10.*win_width), int(0.9/20.*win_height))
        self.lbl_list1.sizeHint = lambda: pg.QtCore.QSize(int(1./10.*win_width), int(0.9/20.*win_height))
        self.lbl_list2.sizeHint = lambda: pg.QtCore.QSize(int(1./10.*win_width), int(0.9/20.*win_height))
        self.list_imgs.sizeHint  = lambda: pg.QtCore.QSize(int(1./10.*win_width), int(18/20.*win_height))
        self.list_marks.sizeHint = lambda: pg.QtCore.QSize(int(1./10.*win_width), int(18/20.*win_height))
        self.list_imgs.setMaximumWidth(int(1./10.*win_width))
        self.list_marks.setMaximumWidth(int(1./10.*win_width))

        self.vtkWidget.show()


if __name__ == "__main__":
    app = QtGui.QApplication([])
    guiobj = GUI()

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

这篇关于将 VTK 插入布局的正确位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆