wxPython and general gui question

I’m on a quest for an easy flexible in-game GUI system. I’d like something very high level with a wysiwig editor perhaps. I’m willing to code it all myself if it comes to that, but I’m trying to find the best launching point.

I have successfully integrated wxPython with Panda3D after reading through a couple demos and examples I’ve found in the forums. Unfortunately I’ve found that my Panda3d applications seem to stop rendering and updating completely when I interact with any of the wx gui conrols or a child window. Is there a way around this? Even if there is, is wxPython really the best starting point for a complex powerful in game gui? If not what do the Panda3d veterans think is the best starting point?

well I passed there time ago and my conclusion was to leave it alone for too many headaches and also there is the problem to have a foreign package more to install distributing your application. I don’t know if you’d seen my try here but just in case not, give it a try maybe still works with 1.7

Thank you for the quick reply!

I did see sample dojo and I was very impressed. Thank you for sharing that great resource. It looks like one could make great use of wxPython for external level editors or something similar.

Unfortunately I haven’t been able to nest any wx controls in a panda3d window without causing execution of the program to halt on their usage. Also I couldn’t figure out a way to get a child window to be rendered in the panda3d window instead of as a seperate window in the operating system. So unless I can figure something out I’m coming to the conclusion that wx is useless to provide in-game GUIs. Especially since you seem to share that opinion.

So does this mean the best option to create a powerful gui system for panda3d is to start with DirectGUI, Tkinter, TreeGUI, Qt, CEGui, create bindings for some other library like Guichan, code one from scratch in the panda3d c++ engine code, or something else? I assume others have put some thought into this. My first priority is getting the best possible GUI system that anyone could pick up and start crafting GUIs with it. I’ll do as much work as needed, but I also want to get there as efficiently as possible, so my first step is going to be the most important.

sorry not to get this - my app it is supposed indeed to work well integrated in a wx window surface not as standalone window so why you see this differently?
Also, I provided samples and lotta comments to explain how to integrate a panda application into that wx cage so I cant get what is you issue with that. Maybe some piece of your code make me help you better.

Forgive me I probably have to look into your code in greater detail. I wanted to start with a small scale test to figure things out so I made the following.

#### wx
from wxPython.wx import *

#### panda3d
from pandac.PandaModules import *
import direct.directbase.DirectStart
from direct.showbase.ShowBase import ShowBase #no handy goodies
from direct.showbase.DirectObject import DirectObject #handy goodies
from direct.task import Task

#### other
from math import pi, sin, cos
import sys


ID_ABOUT = 101
ID_EXIT  = 102

class ParentFrame(wxMDIParentFrame):
    def __init__(self, parent, ID, title):
        wxFrame.__init__(self, parent, ID, title,
                         wxDefaultPosition, wxSize(800, 600))
        self.CreateStatusBar()
        self.SetStatusText("This is the statusbar")

        menu = wxMenu()
        menu.Append(ID_ABOUT, "&About",
                    "More information about this program")
        menu.AppendSeparator()
        menu.Append(ID_EXIT, "E&xit", "Terminate the program")

        menuBar = wxMenuBar()
        menuBar.Append(menu, "&File");

        self.SetMenuBar(menuBar)

class ChildFrame(wxMDIChildFrame):
    def __init__(self, parent, ID, title):
        wxFrame.__init__(self, parent, ID, title,
                         wxDefaultPosition, wxSize(200, 150))
        self.CreateStatusBar()
        self.SetStatusText("This is the statusbar")

        menu = wxMenu()
        menu.Append(ID_ABOUT, "&About",
                    "More information about this program")
        menu.AppendSeparator()
        menu.Append(ID_EXIT, "E&xit", "Terminate the program")

        menuBar = wxMenuBar()
        menuBar.Append(menu, "&File");

        self.SetMenuBar(menuBar)



class AppType(wxPySimpleApp, DirectObject):
    def __init__(self):
        wxPySimpleApp.__init__(self) 
        print "Application Initializing. Hold on to your butts."
        ###shortcuts
        self.loader = loader
        self.taskMgr = taskMgr
        self.camera = base.camera
        
        #Create a new event loop (to overide default wxEventLoop)
        self.evtloop = wxEventLoop()
        self.old = wxEventLoop.GetActive()
        wxEventLoop.SetActive(self.evtloop)
        taskMgr.add(self.wx,"Custom wx Event Loop")
        # wxWindows calls this method to initialize the application

    # wxWindows calls this method to initialize the application
    def OnInit(self):
        self.SetAppName('My wx app')
        self.SetClassName('MyAppClass')

        self.SetAppName('Editor')
        self.SetClassName('MyAppClass')

        self.parent = ParentFrame(None, -1, 'super cool app')
        self.child = ChildFrame(self.parent, -1, 'Panda3D')

        #Main Window
        self.parent.SetClientSize((800, 600))
        self.parent.Show(True)
        #self.parent.ShowFullScreen(True)

        #Child Window
        self.child.SetClientSize((200, 150))
        self.child.Show(True)

        base.windowType = 'onscreen'
        props = WindowProperties.getDefault()
        #props.setParentWindow(self.child.GetHandle())
        props.setParentWindow(self.parent.GetHandle())
        props.setOrigin(0,0)
        base.openDefaultWindow(props = props)
        base.setFrameRateMeter(True)

        self.child.SetFocus()
        return True

    def wx(self,task):
        while self.evtloop.Pending():
            self.evtloop.Dispatch()
        #Thread.sleep(0.01)
        self.ProcessIdle()
        return Task.cont
    def close(self):
        wxEventLoop.SetActive(self.old)
        self.parent.Bind(wx.EVT_CLOSE,sys.exit)
    def run(self):
        run()


p3dApp = AppType()

# Load the environment model.
environ = p3dApp.loader.loadModel("models/environment")
# Reparent the model to render.
environ.reparentTo(render)
# Apply scale and position transforms on the model.
environ.setScale(0.25, 0.25, 0.25)
environ.setPos(-8, 42, 0)

# Define a procedure to move the camera.
def spinCameraTask(task):
  angleDegrees = task.time * 6.0
  angleRadians = angleDegrees * (pi / 180.0)
  p3dApp.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
  p3dApp.camera.setHpr(angleDegrees, 0, 0)
  return Task.cont

# Add the procedure to the task manager.
p3dApp.taskMgr.add(spinCameraTask, "SpinCameraTask")

# Run the engine.
p3dApp.run()

It doesn’t work very well as you can see.

Actually I’m having the same problem with p3d dojo. If you click any of the menu buttons. The panda 3d simulation halts. That’s really not tolerable for an in-game gui.

Also I want a game to run in full screen with a gui overlayed over it. Most games do this these days. p3d dojo and other wx examples I’ve seen never layer gui over the panda3d render. It just has its own space apart from everything else I want to have transparent windows within panda3d’s render and stuff like that.

that code above would never ever run in the dojo construct. Each demo you’ll see running in (have you ever open up a main.py in the rooms section?) is made specifically to run in the construct. Here a little sample:

'''
summary: sequence snippet
by: fabius astelix @2009-07
'''
# Panda imports
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *
#from direct.task import Task
from direct.interval.IntervalGlobal import *
from direct.gui.OnscreenText import OnscreenText

class World(DirectObject):
  #------------------------------------------------------
  #
  def __init__(self):
    DirectObject.__init__(self)

    # initialize with a blank sequence
    self.seq=Sequence(Wait(0.0))

    self._dbgost=OnscreenText(
      text="""'spacebar' to start
'escape' to stop
'backspace' to finish
""", fg=(0,.4,1,1), bg=(1,1,1,1), scale=.1,
    )
    self._dbgost_buf=""
    self.accept('backspace', self.finish_seq)
    self.accept('escape', self.stop_seq)
    self.accept('space', self.start_seq)
  #------------------------------------------------------
  #
  def start_seq(self):
    if self.seq.isPlaying():
      self.printout("* the sequence is just playing *")
      return

    self.printout("* sequence starts *", True)
    self.seq=Sequence(
      Wait(1.0),
      Func(self.printout, 'one' ),
      Wait(2.0),
      Func(self.printout, 'two',),
      Wait(2.0),
      Func(self.printout, 'three'),
      Wait(2.0),
      Func(self.printout, '* sequence ends here *'),
    )
    self.seq.start()
  #------------------------------------------------------
  #
  def stop_seq(self):
    if self.seq.isPlaying():
      self.printout("! sequence stopped by user !")
      self.seq.pause()
    else:
      self.printout("* sequence is just stopped *",True)
  #------------------------------------------------------
  #
  def finish_seq(self):
    if self.seq.isPlaying():
      self.printout("! sequence finished by user !")
      self.seq.finish()
  #------------------------------------------------------
  #
  def printout(self, text, clearbuffer=False):
    if clearbuffer: self._dbgost_buf=text
    else: self._dbgost_buf+="\n"+text
    self._dbgost.setText(self._dbgost_buf)
#-------------------------------------------------------
pea=World()
if __name__ == "__main__":
  run()

as you can see is so not structured as you made and no WX definition needed because already are settled into the dojo construct.
About the menu halting the simulation that’s not happening to me on my linux desktop but beside I don’t recall this issue in windows it is easy that works as well there too, therefore I’m asking to you: have you tried some of the sample provided? will be blocked the execution while opening a menu?
Then, about to have panda3d in fulscreen and GUI that is impossible to achieve with WX for sure - if this is what you want then you got to go with the internal panda primitives of the DirectGUI library or ransack the forums to see what other custom stuff ppl did.

The code I posted above was a standalone program I made while experimenting with wx and panda. It was not designed to work with panda3d dojo.

Also every single demo that comes with panda3d dojo will stall while interacting with any of the menus on my system. I can upload a video I screen captured on youtube later.

no I guess is not necessary - I guess is better know how is your current system situation - panda version, python and WX and of course what OS all is up.

OS: Windows XP
Panda: 1.7.0
Wx: 2.8 unicode
Python: 2.6

Nothing too unusual I think.

I’m just coming to test your setup on my winxp and indeed is as you said. Unfortunately I can’t help you more than this and also, as I told you before, I’d dropped (as much as other ppl before) WX because of kinda issues so I guess that you’re your own with it.

I haven’t really been following this thread, but have you tried simply calling base.startWx(), and inheriting your app from WxAppShell, as the new wx-based LevelEditor does?

David

ow, that sounds new to me - where we could find the leveleditor and some docs about this?

It’s in CVS, in direct/src/leveleditor/.

https://discourse.panda3d.org/viewtopic.php?t=7279

ah thankyou guys - this is something definitely to check it out

That’s the same behavior as on moving or resizing the window.
Linuxes don’t halt the process, unlike Windows.