Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Qt Functionality out of pyvista #614

Closed
akaszynski opened this issue Feb 13, 2020 · 5 comments · Fixed by #719
Closed

Move Qt Functionality out of pyvista #614

akaszynski opened this issue Feb 13, 2020 · 5 comments · Fixed by #719
Labels
discussion Thought provoking threads where decisions have to be made

Comments

@akaszynski
Copy link
Member

We were considering adding additional features to BackgroundPlotter like adding in a tree view. Should we simply move these to the pyvista-gui? Having a Paraview-esque GUI might be the direction we can move pyvista-gui in, rather than simply making it a plug and play module for other programs.

With my closed source project, there are too many variations and some of them require monkey patching the GUI to such a degree that it creates extra work. Why not go with @GuillaumeFavelier 's suggestion and have advanced functionality for the BackgroundPlotter in pyvista-gui.

To tell you the truth, with the problems we had with BackgroundPlotter, I'm half tempted to move it all to pyvista-gui. We can then control the PyQt5 version and do better testing there. pyvista is becoming a bit of a monster these days and it might be better to split it up.

@pyvista/developers, thoughts? Might open a separate thread on slack/gitter.

@akaszynski akaszynski added the discussion Thought provoking threads where decisions have to be made label Feb 13, 2020
@akaszynski akaszynski changed the title Move Qt Functionality out of pyvista Move Qt Functionality out of pyvista Feb 13, 2020
@GuillaumeFavelier
Copy link
Contributor

GuillaumeFavelier commented Feb 13, 2020

To tell you the truth, with the problems we had with BackgroundPlotter, I'm half tempted to move it all to pyvista-gui

I didn't check the design in pyvista-gui in details so I don't know how modular it can be but I can say that in mne-python there is a need for such a lightweight interactive plotter. I assumed that the plotter in pyvista-gui ships with all the big features by default.

Whatever is decided, I would prefer to do it incrementally. It gives more space to adapt/fix what is unexpected.

@banesullivan
Copy link
Member

My thoughts: pyvista should hold the QtInteractor, MainWindow, and BackgroundPlotter classes which are stripped down to the most basic of features and meant to be inherited by other projects. Whereas pyvista-gui will have its own MainWindow class that inherits from pyvista.MainWindow which will be expanded to have the tree widget and other cool features like pop up windows for editing the active scalar array, color map, opacity, etc.

We should strip down the BackgroundPlotter in PyVista and make it as simple as possible to avoid having a complicated API that tends to break in the main PyVista package.

My goal is to make the pyvista_gui.MainWindow class super extensible and out of the box have a tree widget, customizable menu bar, and a full suite of features that can be easily extended for whatever goals (this will look very ParaView-esque). I have a vision of how we could design this MainWindow class to easily let downstream projects customize menus, etc., and still have quick/easy access to the plotter while letting PyVista manage all of the spatial data used through VTK data objects. I think there will be some ways we can design the GUI to avoid monkey patching and really make a useful API for building custom applications.

I also have a handful of ideas for demo applications to show this off, so when I get the time, I'd really like to lead the charge on this... but it may be a while...

@GuillaumeFavelier
Copy link
Contributor

We should strip down the BackgroundPlotter in PyVista and make it as simple as possible to avoid having a complicated API that tends to break in the main PyVista package.

+100 on this

My goal is to make the pyvista_gui.MainWindow class super extensible and out of the box have a tree widget, customizable menu bar, and a full suite of features that can be easily extended for whatever goals (this will look very ParaView-esque)

Also this sounds awesome

@akaszynski
Copy link
Member Author

Agreed. Does this mean moving toolbars and all but the most basic of menus out of BackgroundPlotter? Also, @banesullivan, will there be a pyvista_gui.MainWindow and pyvista.MainWindow?

@banesullivan
Copy link
Member

banesullivan commented Feb 13, 2020

Does this mean moving toolbars and all but the most basic of menus out of BackgroundPlotter

Maybe.... I like the toolbars... It might be nice to keep the camera toolbars in the QtInteractor class so both guis can use them

will there be a pyvista_gui.MainWindow and pyvista.MainWindow?

At the moment, that's what I am thinking.

pyvista.MainWindow will be super basic and meant to simplify this example so that the user doesn't have to set up the QtInteractor or anything. Just inherit pyvista.MainWindow, access the plotter and the menu bar as a properties, add what you need and it'll just work. Below is a prototype of this class

import pyvista as pv
from PyQt5 import Qt
import numpy as np


# prototype of PyVista's `MainWindow` class
class MainWindow(Qt.QMainWindow):

    def __init__(self, parent=None, show=True):
        Qt.QMainWindow.__init__(self, parent)

        vlayout = Qt.QVBoxLayout()
        # add the pyvista interactor object
        self.plotter = pv.QtInteractor(self.main_frame)
        vlayout.addWidget(self.plotter.interactor)
        self.main_frame.setLayout(vlayout)
        self.setCentralWidget(self.main_frame)

        # simple menu
        exit_button = Qt.QAction('Exit', self)
        exit_button.setShortcut('Ctrl+Q')
        exit_button.triggered.connect(self.close)
        self.file_menu.addAction(exit_button)

        if show:
            self.show()
            
    @property
    def main_menu(self):
        if not hasattr(self, "_main_menu"):
            self._main_menu = self.menuBar()
        return self._main_menu
    
    @property
    def file_menu(self):
        if not hasattr(self, "_file_menu"):
            self._file_menu = self.main_menu.addMenu('File')
        return self._file_menu
    
    @property
    def main_frame(self):
        if not hasattr(self, "_main_frame"):
            self._main_frame = Qt.QFrame()
        return self._main_frame
        
        
    def add_menu(self, name):
        return self.main_menu.addMenu(name)
    
    def add_action(self, title, callback, holder):
        action = Qt.QAction(title, self)
        action.triggered.connect(callback)
        holder.addAction(action)
        return action
        
        
# What a user would wright
class UserWindow(MainWindow):
    def __init__(self, *args, **kwargs):
        super(UserWindow, self).__init__(*args, **kwargs)
         # allow adding a sphere
        self.mesh_menu = self.add_menu('Mesh')
        self.add_action("Add Sphere", self.add_sphere, self.mesh_menu)
        
    def add_sphere(self):
        """ add a sphere to the pyqt frame """
        sphere = pv.Sphere()
        self.plotter.add_mesh(sphere)
        self.plotter.reset_camera()

Then pyvista_gui.MainWindow would inherit that and go a bit further as far as menus, widgets, and what not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Thought provoking threads where decisions have to be made
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants