JacobBumgarner / VesselVio

An open-source application for the analysis and visualization of segmented vasculature datasets
https://jacobbumgarner.github.io/VesselVio/
GNU General Public License v3.0
100 stars 21 forks source link

Could not find the Qt platform plugin "xcb" #12

Closed saskra closed 2 years ago

saskra commented 2 years ago

Thanks for this great software. Since my Windows machine struggles a bit with visualization, I would like to use it on my much better equipped Linux server. VVTerminal.py also runs there, but unfortunately VesselVio.py does not, although it is the graphics that matter to me. There I get the following error message:

qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in "/home/saskra/anaconda3/envs/vesselvio/lib/python3.9/site-packages/cv2/qt/plugins"
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Any tips what I could do there? (If I install opencv-python-headless instead of opencv-python, the only change in the error message is that the path is then empty).

JacobBumgarner commented 2 years ago

Hi @saskra. I originally tried developing VesselVio in an anaconda environment, but I was running into a lot of issues with PyQt5.

Would you be willing to try to build VesselVio using a pyenv virtual environment on python 3.8.8? Example builds for Windows and macOS can be found on the build instructions page. I don't have any experience with linux, so maybe if you get this figured out, you could help me write build instructions documentation for linux?

Also - the versions listed in the requirements.txt file are important - make sure you install those package versions!

saskra commented 2 years ago

Thanks for the hint, but with pyenv unfortunately only the type of error changes compared to conda. In the following line it simply does not go on, without error message or abort:

https://github.com/JacobBumgarner/VesselVio/blob/47d0b4a940210c01413ca4dc85ed352597176974/VesselVio.py#L48

Any other ideas?

PS: By the way, I have no problems with Qt in my conda environment on Windows.

JacobBumgarner commented 2 years ago

Thanks for the update - and for letting me know that the app works in conda on Windows. That’s some good news, at least!

Ok - can you do two things for me?

  1. Could you pip -m freeze your environment and share the package versions here?
  2. Can you share the error report with the QtInteractor()? This seems like a pyvista problem.

Hopefully we can get this figured out! It would be great to have the app compatible with Linux :)

saskra commented 2 years ago
1. Could you `pip -m freeze` your environment and share the package versions here?

I did pip freeze and compared the output with the requirements.txt - there are no differences.

Interestingly, by the way, I can achieve exactly the same if I create a conda environment, but except for Python and pip itself, install all packages afterwards using pip within that environment.

2. Can you share the error report with the `QtInteractor()`?  This seems like a pyvista problem.

Unfortunately, there is no error message. I found out the corresponding line where it gets stuck only by writing myself additional console output in the source code.

JacobBumgarner commented 2 years ago

Frustrating.

Can you pip install -U pyvista pyvistaqt and try again? These packages are going to be updated in the next release anyway.

saskra commented 2 years ago

Unfortunately no effect.

However, I don't work with graphical interfaces otherwise so far. That's why I'm particularly interested in this part, but that's also why I can only contribute with little troubleshooting experience in this area myself...

JacobBumgarner commented 2 years ago

That's ok @saskra. Ideally we can work to figure this out together! Unfortunately, I don't have access to a linux machine and have very limited experience with linux, so I'm doing my best to trouble shoot through you.

Since it seems like we've narrowed this down to being an issue with pyvista, can you run the following code using python? I just want to make sure that the pyvista plotter works on your machine.

import pyvista as pv
p = pv.Plotter()
sphere = pv.Sphere()
p.add_mesh(sphere)
p.show()

If that works, can you then try to run this snippet?

import pyvista as pv
from pyvistaqt import BackgroundPlotter

p = BackgroundPlotter()
sphere = pv.Sphere()
p.add_mesh(sphere)
p.app.exec_()

This might help us narrow down whether the problem is coming from VesselVio, pyvista, or pyvistaqt.

Thanks

saskra commented 2 years ago

I have tested both under Windows and Linux - with identical results. The second one works, the first one gives the following error message, but it should not be the reason for the original error. So basically these two packages seem to work on Linux in these versions within the other requirements of this environment.

p(sphere)
TypeError: 'Plotter' object is not callable
JacobBumgarner commented 2 years ago

The first error was a typo on my end - it should've been p.add_mesh(sphere). I've updated this in the comment.

Let's take another step by looking at the QtInteractor now. Does the following code run and work in your environment?

import sys
import pyvista as pv
from pyvistaqt import QtInteractor
from PyQt5.QtWidgets import (QMainWindow, QApplication, QWidget,
                             QVBoxLayout, QHBoxLayout, QCheckBox)

class MainWindow(QMainWindow):
    """Testing main window to understand the QtInteractor on Linux
    """
    def __init__(self):
        super().__init__()
        # Set up page
        self.setWindowTitle("Linux Test")
        centralWidget = QWidget()
        windowLayout = QHBoxLayout()
        self.setCentralWidget(centralWidget)
        centralWidget.setLayout(windowLayout)

        self.plotter = QtInteractor()

        # Set up buttons
        self.sphere_button = QCheckBox('Show Sphere')
        self.sphere_button.toggled.connect(self.toggle_sphere)

        self.axis_button = QCheckBox('Show Axis')
        self.axis_button.toggled.connect(self.toggle_axis)

        buttonLayout = QVBoxLayout()
        buttonLayout.addStretch(0)
        buttonLayout.addWidget(self.sphere_button)
        buttonLayout.addWidget(self.axis_button)
        buttonLayout.addStretch(0)

        # Set up page
        windowLayout.addLayout(buttonLayout)
        windowLayout.addWidget(self.plotter)
        return  

    def toggle_sphere(self):
        """Hide and show a sphere on the plotter
        """
        if self.sphere_button.isChecked():
            sphere = pv.Sphere()
            self.actor = self.plotter.add_mesh(sphere)
        else:
            self.plotter.remove_actor(self.actor)
        return

    def toggle_axis(self):
        """Hide and show the plotter axes
        """
        if self.axis_button.isChecked():
            self.plotter.add_axes()
        else:
            self.plotter.hide_axes()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
saskra commented 2 years ago
        self.plotter = QtInteractor()

Again, this is where it gets stuck.

JacobBumgarner commented 2 years ago

Ok - well then I think we can confidently say that this is a pyvistaqt issue, and not directly a Vesselavio issue at the moment.

Because I don’t have a Linux machine, I don’t feel comfortable opening this issue on the pyvistaqt page, because I won’t be able to help them with troubleshooting. Would you be willing to do this and share the three sets of code above that help identify where the crash is occurring?

See their GitHub here.

JacobBumgarner commented 2 years ago

Or you could move through the QtInteractor class line-by-line to see where the crash is occurring?

https://github.com/pyvista/pyvistaqt/blob/main/pyvistaqt/plotting.py

saskra commented 2 years ago

Would you be willing to do this and share the three sets of code above that help identify where the crash is occurring?

I did: https://github.com/pyvista/pyvistaqt/issues/158

Thanks again for the effort!

saskra commented 2 years ago

So the solution was very simple in the end:

- self.plotter = QtInteractor()
+ self.plotter = QtInteractor(self)

Now, unfortunately, no file dialog opens when I go to "Load Files" or "Select", but maybe that will be the subject of another issue sometime.

JacobBumgarner commented 2 years ago

+1 Awesome. Thanks for helping to get this one sorted out @saskra !

Does the lack of dialog apply to both the Analysis and Visualization page? I wonder if I'm passing the main window along to those classes 🤔

saskra commented 2 years ago

Yes, both pages affected.