multiple windows under wx

Dear Forum,

i’m trying to set up an App with 3 splitter windows containing perspective,top,and front view and there are some issues. I hope you can point me in the right direction to resolve them (code based on snipplets found in the forum)

import wx

from direct.showbase.ShowBase import ShowBase
from direct.wxwidgets.ViewPort import Viewport
from direct.wxwidgets.WxPandaWindow import WxPandaWindow
import panda3d.core as core

core.loadPrcFileData('startup', 'window-type none')

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        
        self.Bind(wx.EVT_SIZE, self.onSize)
        
        self.split1 = wx.SplitterWindow(self)
        self.split2 = wx.SplitterWindow(self.split1)           
        
        self.p0 = wx.Panel (self.split1)
        self.p1 = wx.Panel (self.split2)
        self.p2 = wx.Panel (self.split2)

        self.p0.SetBackgroundColour((200,25,50))
        self.p1.SetBackgroundColour((25,200,50))
        self.p2.SetBackgroundColour((25,25,200))
        
        self.split2.SetMinimumPaneSize(10)
        self.split2.SplitHorizontally(self.p1,self.p2,400) 
        self.split1.SetMinimumPaneSize(10)
        self.split1.SplitVertically(self.p0,self.split2,300)  

        self.split1.SetPosition((0,0))
        self.split1.SetSize((800,600))
        self.split2.SetSashPosition(300)       

        self.panda =  WxPandaWindow(parent = self.p0)
        self.panda1 = WxPandaWindow(parent = self.p1)       
        self.panda2 = WxPandaWindow(parent = self.p2)
        
        self.onSize(1)
   
    def onQuit(self, evt):
        self.Close()
        
    def onSize(self, evt):
        self.split1.SetSize((self.GetSize().width,self.GetSize().height))
        self.p0.SetSize((-1,-1))
        self.p1.SetSize((-1,-1))
        self.p2.SetSize((-1,-1))

class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self, fStartDirect=False, windowType=None)       
        # setup application window       
        self.startWx()
        self.wxApp.Bind(wx.EVT_CLOSE, self.quit)
        self.frame = Frame(None, wx.ID_ANY, 'Editor', size=(800, 600))

        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(400,300)
        wp.setParentWindow(self.frame.panda.GetHandle())
        base.openMainWindow(type = 'onscreen', props=wp)
        base.setBackgroundColor(0,1,0,1)
        
        wp1 = core.WindowProperties()
        wp1.setOrigin(0,0)
        wp1.setSize(400,300)
        wp1.setParentWindow(self.frame.panda1.GetHandle())
        base.openWindow(type = 'onscreen', props=wp1)
        base.setBackgroundColor(1,1,0,1)
        
        wp2 = core.WindowProperties()
        wp2.setOrigin(0,0)
        wp2.setSize(400,300)
        wp2.setParentWindow(self.frame.panda2.GetHandle())
        base.openWindow(type = 'onscreen', props=wp2)
        base.setBackgroundColor(1,1,1,1)        

        self.frame.Show()
       
        # setup mouse/picking/selection system

        def foo():
            print "debug"
        self.accept("mouse1", foo)
        self.accept("mouse3", foo)
        self.accept("t", foo)

    def quit(self, event=None):
        self.onDestroy(event)
        try:
            base
        except NameError:
            sys.exit()
        base.userExit()

app = App()
app.run()

Why do the WxPandawindows not size to 400,300 ?
Why is only the 1st window affected by the colour change ?
how do I get the other windows to accept mouse/keyboard input?

with best wishes

Martin

Ok, wxpandawindow as child of splitterwindow with size of parent window seems to be doing the sizing problem.

import wx

from direct.showbase.ShowBase import ShowBase
from direct.wxwidgets.ViewPort import Viewport
from direct.wxwidgets.WxPandaWindow import WxPandaWindow
import panda3d.core as core

core.loadPrcFileData('startup', 'window-type none')

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        
        self.Bind(wx.EVT_SIZE, self.onSize)
        
        self.split1 = wx.SplitterWindow(self)
        self.split2 = wx.SplitterWindow(self.split1)           
        
        self.p0 = WxPandaWindow(parent = self.split1)
        self.p1 = WxPandaWindow(parent = self.split2)       
        self.p2 = WxPandaWindow(parent = self.split2)

        self.split2.SetMinimumPaneSize(10)
        self.split2.SplitHorizontally(self.p1,self.p2,400) 
        self.split1.SetMinimumPaneSize(10)
        self.split1.SplitVertically(self.p0,self.split2,300)  

        self.split1.SetPosition((0,0))
        self.split1.SetSize((800,600))
        self.split2.SetSashPosition(300)       
        
        self.onSize(1)
   
    def onQuit(self, evt):
        self.Close()
        
    def onSize(self, evt):
        self.split1.SetSize((self.GetSize().width,self.GetSize().height))
        self.p0.SetSize((-1,-1))
        self.p1.SetSize((-1,-1))    
        self.p2.SetSize((-1,-1))      


class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self, fStartDirect=False, windowType=None)       
        # setup application window       
        self.startWx()
        self.frame = Frame(None, wx.ID_ANY, 'Editor', size=(800, 600))
        self.wxApp.Bind(wx.EVT_CLOSE, self.quit)
        self.wxApp.Bind(wx.EVT_SIZE , self.OnResize)

        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(self.frame.p0.GetSize().width,self.frame.p0.GetSize().height)
        wp.setParentWindow(self.frame.p0.GetHandle())
        self.win = base.openWindow(type = 'onscreen', props=wp)
        base.setBackgroundColor(0,1,0,1) 
        
        wp1 = core.WindowProperties()
        wp1.setOrigin(10,10)
        wp1.setSize(self.frame.p1.GetSize().width,self.frame.p1.GetSize().height)
        wp1.setParentWindow(self.frame.p1.GetHandle())
        self.win1 = base.openWindow(type = 'onscreen', props=wp1)
        base.setBackgroundColor(1,1,0,1)
        
        wp2 = core.WindowProperties()
        wp2.setOrigin(0,0)
        wp2.setSize(self.frame.p2.GetSize().width,self.frame.p2.GetSize().height)
        wp2.setParentWindow(self.frame.p2.GetHandle())
        self.win2 = base.openWindow(type = 'onscreen', props=wp2)
        base.setBackgroundColor(1,1,1,1)        

        self.frame.Show()
       
        # setup mouse/picking/selection system

        def foo():
            print "debug"
        self.accept("mouse1", foo)
        self.accept("mouse3", foo)
        self.accept("t", foo)
        
    def OnResize(self, event):
        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(self.frame.p0.GetSize().width,self.frame.p0.GetSize().height)
        self.win.requestProperties(wp)
        wp.setSize(self.frame.p1.GetSize().width,self.frame.p1.GetSize().height)
        self.win1.requestProperties(wp)
        wp.setSize(self.frame.p2.GetSize().width,self.frame.p2.GetSize().height)
        self.win2.requestProperties(wp)         

    def quit(self, event=None):
        self.onDestroy(event)
        try:
            base
        except NameError:
            sys.exit()
        base.userExit()

app = App()
app.run()

The colour and mouse thing are still open…

with kind regards

Martin

Further Experiments yielded:

import wx

from direct.showbase.ShowBase import ShowBase

from direct.wxwidgets.WxPandaWindow import WxPandaWindow

from pandac.PandaModules import VBase4
from pandac.PandaModules import NodePath
from pandac.PandaModules import Camera

import panda3d.core as core

core.loadPrcFileData('startup', 'window-type none')

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.split1 = wx.SplitterWindow(self)        
        sizer.Add(self.split1,1,flag=wx.EXPAND)
        
        self.split2 = wx.SplitterWindow(self.split1)           
        
        self.p0 = wx.Panel(self.split1)
        self.p1 = wx.Panel(self.split2)       
        self.p2 = wx.Panel(self.split2)

        self.split2.SetMinimumPaneSize(10)
        self.split2.SplitHorizontally(self.p1,self.p2,400) 
        self.split1.SetMinimumPaneSize(10)
        self.split1.SplitVertically(self.p0,self.split2,250)  

        self.split1.SetPosition((0,0))
        self.split1.SetSize((800,600))
        self.split2.SetSashPosition(300)
        
   
    def onQuit(self, evt):
        self.Close()  


class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self, fStartDirect=False, windowType=None)              
        self.startWx()
        self.frame = Frame(None, wx.ID_ANY, 'Editor', size=(800, 600))

        self.wxApp.Bind(wx.EVT_CLOSE, self.quit)
        self.wxApp.Bind(wx.EVT_SIZE , self.OnResize)
        
        env = self.loader.loadModel("models/environment")
        env.reparentTo(render)
        env.setScale(0.025, 0.025, 0.025)
        env.setPos(-8, 42, 0)
        
        base.disableMouse()
        
        wp0 = core.WindowProperties()
        wp0.setOrigin(0,0)
        wp0.setSize(self.frame.p0.GetSize().width,self.frame.p0.GetSize().height)
        wp0.setParentWindow(self.frame.p0.GetHandle())
        self.win0 = base.openWindow(type = 'onscreen', props=wp0)
        self.dr = self.win0.makeDisplayRegion()
        self.dr.setClearColor(VBase4(1, 0, 0, 1))
        self.dr.setClearColorActive(True)
        self.dr.setClearDepthActive(True)        
        camNode = Camera('cam')
        camNP = NodePath(camNode)
        self.dr.setCamera(camNP)
        camNP.reparentTo(base.camera)
        
        
        
        
        wp1 = core.WindowProperties()
        wp1.setOrigin(0,0)
        wp1.setSize(self.frame.p1.GetSize().width,self.frame.p1.GetSize().height)
        wp1.setParentWindow(self.frame.p1.GetHandle())
        self.win1 = base.openWindow(type = 'onscreen', props=wp1)
        self.dr1 = self.win1.makeDisplayRegion()
        self.dr1.setClearColor(VBase4(0, 1, 0, 1))
        self.dr1.setClearColorActive(True)
        self.dr1.setClearDepthActive(True)         
        camNode1 = Camera('cam1')
        camNP1 = NodePath(camNode1)
        self.dr1.setCamera(camNP1)
        camNP1.reparentTo(base.camera)
        
        
        wp2 = core.WindowProperties()
        wp2.setOrigin(0,0)
        wp2.setSize(self.frame.p2.GetSize().width,self.frame.p2.GetSize().height)
        wp2.setParentWindow(self.frame.p2.GetHandle())
        self.win2 = base.openWindow(type = 'onscreen', props=wp2)
        self.dr2 = self.win2.makeDisplayRegion()
        self.dr2.setClearColor(VBase4(0, 0, 1, 1))
        self.dr2.setClearColorActive(True)
        self.dr2.setClearDepthActive(True)        
        camNode2 = Camera('cam2')
        camNP2 = NodePath(camNode2)
        self.dr2.setCamera(camNP2)
        camNP2.reparentTo(base.camera)        


        self.frame.Show()
       
        # setup mouse/picking/selection system

        def foo():
            print "debug"
        self.accept("mouse1", foo)
        self.accept("mouse3", foo)
        self.accept("t", foo)
        
    def OnResize(self, event):
        pass
        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(self.frame.p0.GetSize().width,self.frame.p0.GetSize().height)
        wp.setParentWindow(self.frame.p0.GetHandle())
        self.win0.requestProperties(wp)
        
        wp1 = core.WindowProperties()
        wp1.setOrigin(0,0)
        wp1.setSize(self.frame.p1.GetSize().width,self.frame.p1.GetSize().height)
        wp1.setParentWindow(self.frame.p1.GetHandle())
        self.win1.requestProperties(wp1)
        
        wp2= core.WindowProperties()
        wp2.setOrigin(0,0)
        wp2.setSize(self.frame.p2.GetSize().width,self.frame.p2.GetSize().height)
        wp2.setParentWindow(self.frame.p2.GetHandle())
        self.win2.requestProperties(wp2)        
        

    def quit(self, event=None):
        self.onDestroy(event)
        try:
            base
        except NameError:
            sys.exit()
        base.userExit()

app = App()
app.run()

but there is still something wrong. The first Window is rendered correct and in the other windows a correct render apears for a short moment and then a white stenciled aerea apears.

an other experiment:

import wx

from direct.showbase.ShowBase import ShowBase

from direct.wxwidgets.WxPandaWindow import WxPandaWindow

from pandac.PandaModules import VBase4
from pandac.PandaModules import NodePath
from pandac.PandaModules import Camera

import panda3d.core as core

core.loadPrcFileData('startup', 'window-type none')

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        
        self.split1 = wx.SplitterWindow(self)        
        sizer.Add(self.split1,1,flag=wx.EXPAND)
        
        self.split2 = wx.SplitterWindow(self.split1)           
        
        self.p0 = wx.Panel(self.split1)
        self.p1 = wx.Panel(self.split2)       
        self.p2 = wx.Panel(self.split2)

        self.split2.SetMinimumPaneSize(10)
        self.split2.SplitHorizontally(self.p1,self.p2,400) 
        self.split1.SetMinimumPaneSize(10)
        self.split1.SplitVertically(self.p0,self.split2,250)  

        self.split1.SetPosition((0,0))
        self.split1.SetSize((800,600))
        self.split2.SetSashPosition(300)
        
   
    def onQuit(self, evt):
        self.Close()  


class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self, fStartDirect=False, windowType=None)              
        self.startWx()
        self.frame = Frame(None, wx.ID_ANY, 'Editor', size=(800, 600))

        self.wxApp.Bind(wx.EVT_CLOSE, self.quit)
        self.wxApp.Bind(wx.EVT_SIZE , self.OnResize)
        
        env = self.loader.loadModel("models/environment")
        env.reparentTo(render)
        env.setScale(0.025, 0.025, 0.025)
        env.setPos(-8, 42, 0)
        
        base.disableMouse()
        
        wp0 = core.WindowProperties()
        wp0.setOrigin(0,0)
        wp0.setSize(self.frame.p0.GetSize().width,self.frame.p0.GetSize().height)
        wp0.setParentWindow(self.frame.p0.GetHandle())
        self.win0 = base.openWindow(type = 'onscreen', props=wp0)
        self.cam0 = base.makeCamera(self.win0, camName = 'cam0')
        self.dr = self.win0.makeDisplayRegion()
        self.dr.setClearColor(VBase4(1, 0, 0, 1))
        self.dr.setClearColorActive(True)
        self.dr.setClearDepthActive(True)        
        #camNode = Camera('cam')
        camNP = NodePath(self.cam0)
        self.dr.setCamera(camNP)
        camNP.reparentTo(base.camera)
        
        
        
        
        wp1 = core.WindowProperties()
        wp1.setOrigin(0,0)
        wp1.setSize(self.frame.p1.GetSize().width,self.frame.p1.GetSize().height)
        wp1.setParentWindow(self.frame.p1.GetHandle())
        self.win1 = base.openWindow(type = 'onscreen', props=wp1)
        self.cam1 = base.makeCamera(self.win1, camName = 'cam1')
        self.dr1 = self.win1.makeDisplayRegion()
        self.dr1.setClearColor(VBase4(0, 1, 0, 1))
        self.dr1.setClearColorActive(True)
        self.dr1.setClearDepthActive(True)         
        #camNode1 = Camera('cam1')
        camNP1 = NodePath(self.cam1)
        self.dr1.setCamera(camNP1)
        camNP1.reparentTo(base.camera)
        
        
        wp2 = core.WindowProperties()
        wp2.setOrigin(0,0)
        wp2.setSize(self.frame.p2.GetSize().width,self.frame.p2.GetSize().height)
        wp2.setParentWindow(self.frame.p2.GetHandle())
        self.win2 = base.openWindow(type = 'onscreen', props=wp2)
        self.cam2 = base.makeCamera(self.win2, camName = 'cam2')
        self.dr2 = self.win2.makeDisplayRegion()
        self.dr2.setClearColor(VBase4(0, 0, 1, 1))
        self.dr2.setClearColorActive(True)
        self.dr2.setClearDepthActive(True)        
        #camNode2 = Camera('cam2')
        camNP2 = NodePath(self.cam2)
        self.dr2.setCamera(camNP2)
        camNP2.reparentTo(base.camera)        


        self.frame.Show()
       
        # setup mouse/picking/selection system

        def foo():
            print "debug"
        self.accept("mouse1", foo)
        self.accept("mouse3", foo)
        self.accept("t", foo)
        
    def OnResize(self, event):
        pass
        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(self.frame.p0.GetSize().width,self.frame.p0.GetSize().height)
        wp.setParentWindow(self.frame.p0.GetHandle())
        self.win0.requestProperties(wp)
        
        wp1 = core.WindowProperties()
        wp1.setOrigin(0,0)
        wp1.setSize(self.frame.p1.GetSize().width,self.frame.p1.GetSize().height)
        wp1.setParentWindow(self.frame.p1.GetHandle())
        self.win1.requestProperties(wp1)
        
        wp2= core.WindowProperties()
        wp2.setOrigin(0,0)
        wp2.setSize(self.frame.p2.GetSize().width,self.frame.p2.GetSize().height)
        wp2.setParentWindow(self.frame.p2.GetHandle())
        self.win2.requestProperties(wp2)        
        

    def quit(self, event=None):
        self.onDestroy(event)
        try:
            base
        except NameError:
            sys.exit()
        base.userExit()

app = App()
app.run()

yields:

but only sometimes

Any ideas?

Martin

Next step:

switching to pandadx9: it renders as it should ---- provided that all 3 cameras are reparented to base.cam

and it’s not stable sometimes it crashes while sliding the splitters