WxPython and Vispy

111 views
Skip to first unread message

Marco

unread,
Feb 4, 2018, 6:47:57 AM2/4/18
to vispy
Hi,
here a newbie question on embedding Vispy's SceneCanvas in a WxPython application.
How to resize SceneCanvas to fit panel? and resize again when resize the window?

import wx
import vispy.scene as scene


class Canvas(scene.SceneCanvas):
   
def __init__(self, *a, **k):
        scene
.SceneCanvas.__init__(self, *a, **k)


class my_panel_1(wx.Panel):
   
def __init__(self, *a, **k):
        wx
.Panel.__init__(self, *a, **k)
       
self.SetBackgroundColour(wx.BLUE)
       
self.canvas = Canvas(app="wx", keys='interactive', parent=self, resizable=True)
       
self.canvas.show()


class my_panel_2(wx.Panel):
   
def __init__(self, *a, **k):
        wx
.Panel.__init__(self, *a, **k)
       
self.SetBackgroundColour(wx.GREEN)
        a_text
= wx.TextCtrl(self, pos=(10, 10))
        a_button
= wx.Button(self, -1, 'Hello Word', pos=(10, 50))

class MyFrame(wx.Frame):
   
def __init__(self, *a, **k):
        wx
.Frame.__init__(self, *a, **k, title="Title", size=(800, 600))

        box
= wx.BoxSizer(wx.HORIZONTAL)

        panel1
= my_panel_1(self)
        box
.Add(panel1, 1, wx.EXPAND)

        box2
= wx.BoxSizer(wx.VERTICAL)
        box
.Add(box2, 0, wx.EXPAND)

        panel2
= my_panel_2(self)
        box2
.Add(panel2, 1, wx.EXPAND)

       
self.SetAutoLayout(True)
       
self.SetSizer(box)
       
self.Layout()


if __name__ == '__main__':
    app
= wx.App(False)
    frame
= MyFrame(None)
    frame
.Show(True)
    app
.MainLoop()

Thanks for your help.

Marco

David Hoese

unread,
Feb 4, 2018, 8:10:01 AM2/4/18
to vispy
I've never put a vispy canvas in to a Wx application, but I can offer a few things to try. First, you shouldn't need the `canvas.show()` and you may want to try removing the `keys='interactive'` parameter. The "resizable" parameter could also be removed since the default is True.

Most importantly, what about this isn't working for you? I have not tested it myself, but are you getting error messages? What version of WxPython are you using?

Dave

Marco

unread,
Feb 4, 2018, 9:28:04 AM2/4/18
to vispy
Thanks for your reply.

There are no errors in console. Simply the SceneCanvas doesn't fit the panel. Its size is always fixed and I don't know how to resize it.

Why use WxPython? Because it is the only GUI library that we can use to realize a commercial desktop app with Vispy without to pay the excessive price of Qt.

Ciao,
Marco

Marco

unread,
Feb 4, 2018, 9:31:06 AM2/4/18
to vispy
About my configuration:
  • Python 3.6
  • WxPython 4.0.0
  • Vispy 0.6.0dev

David Hoese

unread,
Feb 4, 2018, 12:15:36 PM2/4/18
to vispy
I've been trying to debug this and I think I got it far enough that you can do what you need. From my understanding you need to add the GLCanvas to a Sizer object for the canvas to get the sizing events properly. You can see in the `simple_wx.py` example in the vispy repository that a single canvas that takes up the whole window gets the resize events fine. I've changed your panel1 to look like this:

class my_panel_1(wx.Panel):
    def __init__(self, *a, **k):
        wx.Panel.__init__(self, *a, **k)
        box = wx.BoxSizer(wx.VERTICAL)
        self.SetBackgroundColour(wx.BLUE)
        self.canvas = Canvas(app="wx", parent=self)
        box.Add(self.canvas.native, 1, wx.EXPAND | wx.ALL)
        self.SetAutoLayout(True)
        self.SetSizer(box)

And everything seems to expand as expected. Note that I moved the canvas show to the main frame by following the `simple_wx.py`'s pattern:

class MyFrame(wx.Frame):
    def __init__(self, *a, **k):
        wx.Frame.__init__(self, *a, **k, title="Title", size=(800, 600))

        box = wx.BoxSizer(wx.HORIZONTAL)

        panel1 = my_panel_1(self)
        self.canvas = panel1.canvas
        # ... other stuff in init ...
        self.Bind(wx.EVT_SHOW, self.on_show)

    def on_show(self, event):
        self.canvas.show()
        event.Skip()

Dave

Marco

unread,
Feb 4, 2018, 1:29:26 PM2/4/18
to vispy
Many thanks David, it works, but I can't add other panel.

self.canvas = panel1.canvas
this line set panel1 as canvas for whole frame
Then I can't add other panels to the BoxSizer

Sorry for my newbie insistence.

Marco

David Hoese

unread,
Feb 4, 2018, 1:36:19 PM2/4/18
to vispy
Marco,

I might be misunderstanding something about Wx, but that line doesn't do anything except keep a handle to the VisPy canvas object so that we can call `.show()` on it later in the Frame. The code I provided shows you how to properly add a VisPy canvas to a Wx Panel and have it respond to resize events. Any sizing issues after that should be considered normal Wx usage. I suggest looking at their examples or documentation for properly sizing things. The VisPy canvas is just a widget in the overall GUI so it shouldn't do anything to surprising. You might have to play around with the various BoxSizers in your code to get things where you want and how you want.

Dave
Reply all
Reply to author
Forward
0 new messages