Search code examples
pythonpython-3.xpyqt5vtk

Displaying vpl.mesh_plot in PyQT5


I need to render an .stl image on an user interface.

I created the UI with PyQt5, and I have managed to render the .stl image with vplotlib. However, I am having problems with displaying this vpl.mesh_plot on the Qframe that I have on UI (name: self.ui.MyQframe; the window does not necessarily need to be of this type, can also be QGraphicsViewer or else).

This is the function that renders the .stl image:

import vtkplotlib as vpl
from stl.mesh import Mesh
def setScan(self):
        path, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "",
                                                            "stl Files (*.stl)")  # Ask for file
        mesh = Mesh.from_file(path)

        vpl.mesh_plot(path)

        vpl.mesh_plot(mesh)

        vpl.show()

##Edit 1: Based on Eyllanesc's answer I changed the QFrame to QtWidget, and set fig=self.MyQtWidget in each vpl.mesh_ ... + changed show() accordingly.

However, it still opens up as a new window & I'm not sure why.

def setScan(self):
    path, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "",
                                                        "stl Files (*.stl)")  
    mesh = Mesh.from_file(path)
    self.MyQtWidget = vpl.QtFigure()

    vpl.mesh_plot(path,fig=self.MyQtWidget)

    vpl.mesh_plot(mesh,fig=self.MyQtWidget)
    self.MyQtWidget.show()

Solution

  • You have to use QtFigure which is QWidget:

    import sys
    
    import vtkplotlib as vpl
    from PyQt5 import QtWidgets
    from stl.mesh import Mesh
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
    
            central_widget = QtWidgets.QWidget()
            self.setCentralWidget(central_widget)
            vbox = QtWidgets.QVBoxLayout(central_widget)
    
            button = QtWidgets.QPushButton("Select STL")
            self.figure = vpl.QtFigure()
            vbox.addWidget(button)
            vbox.addWidget(self.figure)
    
            button.clicked.connect(self.select_filename)
            self.figure.show()
    
        def select_filename(self):
            path, _ = QtWidgets.QFileDialog.getOpenFileName(
                None, "Select Image", "", "stl Files (*.stl)"
            )
            if path:
                self.load_mesh(path)
    
        def load_mesh(self, filename):
            mesh = Mesh.from_file(filename)
            vpl.mesh_plot(mesh, fig=self.figure)
    
    
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())