Skip to content

Embedding in PyQt #340

Closed
Closed

Description

@joeyo

Here is a minimal example example that should work with Qt:

import fastplotlib as fpl
plot = fpl.Plot(canvas="qt")
plot.show()

if __name__ == "__main__":
    fpl.run()

With these packages installed:

wgpu==0.11.0
pygfx==0.1.15
fastplotlib==0.1.0a13
PyQt6==6.5.3

the following error message is generated (similar errors occur with PyQt5, PySide2, and PySide6):

Traceback (most recent call last):
  File "/Users/joeyo/src/bmi/analysis/joeyo/fpl/qt_minimal.py", line 3, in <module>
    plot = fpl.Plot(canvas="qt")
  File "/opt/homebrew/lib/python3.10/site-packages/fastplotlib/layouts/_plot.py", line 54, in __init__
    super(Plot, self).__init__(
  File "/opt/homebrew/lib/python3.10/site-packages/fastplotlib/layouts/_subplot.py", line 77, in __init__
    canvas, renderer = make_canvas_and_renderer(canvas, renderer)
  File "/opt/homebrew/lib/python3.10/site-packages/fastplotlib/layouts/_utils.py", line 50, in make_canvas_and_renderer
    raise ImportError(
ImportError: The qt framework is not installed for using this canvas

Which suggests that fastplotlib/layouts/_utils.py:17 is raising an ImportError:

16 try:
17    from wgpu.gui.qt import QWgpuCanvas
18 except ImportError:
19    QWgpuCanvas = False

However the following will run without errors:

import PyQt6  # apparently necessary
from wgpu.gui.qt import QWgpuCanvas

Is there some missing import logic?

Activity

  1. kushalkolar commented on Oct 26, 2023

    @kushalkolar
    Member

    You'll need to encapsulate it within a Qt app, I'll make an example later today.

  2. kushalkolar commented on Oct 26, 2023

    @kushalkolar
    Member

    By the way, @EricThomson says hi 😄

  3. kushalkolar commented on Oct 26, 2023

    @kushalkolar
    Member

    @joeyo

    Here's an example with video and a slider. Qt is quite tedious which is why I mostly use ipywidgets these days 😄

    #341

    """
    Use a simple Plot to display a video frame that can be updated using a QSlider
    """
    from PyQt6 import QtWidgets, QtCore
    import fastplotlib as fpl
    import imageio.v3 as iio
    
    # Qt app MUST be instantiated before creating any fpl objects, or any other Qt objects
    app = QtWidgets.QApplication([])
    
    video = iio.imread("imageio:cockatoo.mp4")
    
    # force qt canvas, wgpu will sometimes pick glfw by default even if Qt is present
    plot = fpl.Plot(canvas="qt")
    
    plot.add_image(video[0], name="video")
    plot.camera.local.scale *= -1
    
    
    def update_frame(ix):
        plot["video"].data = video[ix]
        # you can also do plot.graphics[0].data = video[ix]
    
    
    # create a QMainWindow, set the plot canvas as the main widget
    # The canvas does not have to be in a QMainWindow and it does
    # not have to be the central widget, it will work like any QWidget
    main_window = QtWidgets.QMainWindow()
    main_window.setCentralWidget(plot.canvas)
    
    # Create a QSlider for updating frames
    slider = QtWidgets.QSlider(QtCore.Qt.Orientation.Horizontal)
    slider.setMaximum(video.shape[0] - 1)
    slider.setMinimum(0)
    slider.valueChanged.connect(update_frame)
    
    # put slider in a dock
    dock = QtWidgets.QDockWidget()
    dock.setWidget(slider)
    
    # put the dock in the main window
    main_window.addDockWidget(
        QtCore.Qt.DockWidgetArea.BottomDockWidgetArea,
        dock
    )
    
    # calling plot.show() is required to start the rendering loop
    plot.show()
    
    # set window size from width and height of video
    main_window.resize(video.shape[2], video.shape[1])
    
    # show the main window
    main_window.show()
    
    # execute Qt app
    app.exec()
  4. joeyo commented on Oct 26, 2023

    @joeyo
    Author

    @kushalkolar Awesome, works out of the box!

    (Hi @EricThomson!)

  5. changed the title [-]Interoperability with PyQt[/-] [+]Embedding in PyQt[/+] on Oct 26, 2023
  6. EricThomson commented on Oct 26, 2023

    @EricThomson
    Contributor

    Hey @joeyo if you are going to SFN there is going to be a fastplotlib code sprint 😄
    https://twitter.com/kushalkolar/status/1706725236719354241

    Maybe a good time to add Qt demo @kushalkolar

  7. kushalkolar commented on Oct 26, 2023

    @kushalkolar
    Member

    @joeyo I just added a minimal Qt example: https://github.com/fastplotlib/fastplotlib/blob/main/examples/qt/minimal.py

    I'm thinking we might make a Qt toolbar as well, so that plots can be QWidgets that come pre-loaded with the toolbar that you get in notebooks.

  8. EricThomson commented on Oct 26, 2023

    @EricThomson
    Contributor

    nevermind Kushal is fast as usual 😆

  9. kushalkolar commented on Oct 31, 2023

    @kushalkolar
    Member

    @joeyo I just merged #313 which implements output contexts, so now plots, gridplots, and even image widgets work the same between Qt and jupyter including the toobars 😄

    You can use the Qt context in standalone Qt applications, or in notebooks by just using %gui qt

    Added qt image widget example here: https://github.com/fastplotlib/fastplotlib/blob/main/examples/qt/imagewidget.py

    Note that the ImageWidget is currently limited to grayscale images/image sequences, it does not handle RBGA. If you want RGBA you will have to add the image graphic yourself and use a gridplot/plot with your own sliders etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions