Panda3d + wxpython not working on macOs, but works on Windows 10

Not sure if this is a known issue (I couldn’t find any recent discussion of this), but I’m trying to run a panda window in a wxpython frame and it crashes on macOs, though it runs fine on Windows 10.

panda3d version: 1.10.7
python: 3.7.7
wxPython (not sure if this is relevant): 4.0.4
macOs: Catalina 10.15.6

Here’s the code:

import wx
from direct.showbase.ShowBase import ShowBase
import panda3d.core as core
from open3d_loader import *

class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        # setup application window     
        print('starting wxApp...')  
        self.startWx()
        print('started!')
        self.wxApp.Bind(wx.EVT_CLOSE, self.quit)
        self.frame = Frame(None, wx.ID_ANY, 'Editor')
        self.frame.Show()
        self.frame.Layout()
    
        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(400,300)
        wp.setParentWindow(self.frame.GetHandle())
        base.openMainWindow(type = 'onscreen', props=wp, size=(800, 600))

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


class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        # add menu
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
        self.Bind(wx.EVT_MENU, self.onQuit, fitem)
        menubar.Append(fileMenu, '&File')
        self.SetMenuBar(menubar)
   
    def onQuit(self, evt):
        self.Close()

if __name__ == '__main__': 
    App().run()

Here’s the output:

Known pipe types:
  CocoaGraphicsPipe
(all display modules loaded.)
starting wxApp...
activate_osx_application
/opt/miniconda3/envs/hfh/lib/python3.7/site-packages/direct/showbase/ShowBase.py:3129: wxPyDeprecationWarning: Using deprecated class PySimpleApp. Use :class:`App` instead.
  self.wxApp = wx.PySimpleApp(redirect = False)
2020-09-17 17:20:34.045 python[24252:330792] -[CocoaPandaApp transformToForegroundApplication]: unrecognized selector sent to instance 0x7fddfe46aa20
2020-09-17 17:20:34.048 python[24252:330792] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CocoaPandaApp transformToForegroundApplication]: unrecognized selector sent to instance 0x7fddfe46aa20'
*** First throw call stack:
(
        0   CoreFoundation                      0x00007fff2df53b57 __exceptionPreprocess + 250
        1   libobjc.A.dylib                     0x00007fff66d9a5bf objc_exception_throw + 48
        2   CoreFoundation                      0x00007fff2dfd2be7 -[NSObject(NSObject) __retain_OA] + 0
        3   CoreFoundation                      0x00007fff2deb83bb ___forwarding___ + 1427
        4   CoreFoundation                      0x00007fff2deb7d98 _CF_forwarding_prep_0 + 120
        5   libwx_osx_cocoau_core-3.0.0.4.0.dyl 0x000000010beb4d7e _ZN5wxApp9DoInitGuiEv + 478
        6   _core.cpython-37m-darwin.so         0x000000010b7ba7ea _ZN10sipwxPyApp9OnInitGuiEv + 186
        7   libwx_osx_cocoau_core-3.0.0.4.0.dyl 0x000000010bf04872 _ZN5wxApp10InitializeERiPPw + 242
        8   libwx_baseu-3.0.0.4.0.dylib         0x000000010c50a633 _Z12wxEntryStartRiPPw + 179
        9   _core.cpython-37m-darwin.so         0x000000010b7be2e6 _ZN7wxPyApp13_BootstrapAppEv + 518
        10  _core.cpython-37m-darwin.so         0x000000010b7be076 _ZL26meth_wxPyApp__BootstrapAppP7_objectS0_ + 102
        11  python                              0x000000010b09cbae _PyMethodDef_RawFastCallKeywords + 350
        12  python                              0x000000010b1da222 call_function + 306
        13  python                              0x000000010b1d6fbd _PyEval_EvalFrameDefault + 42221
        14  python                              0x000000010b1cb89e _PyEval_EvalCodeWithName + 414
        15  python                              0x000000010b09b7c7 _PyFunction_FastCallDict + 231
        16  python                              0x000000010b1d8130 _PyEval_EvalFrameDefault + 46688
        17  python                              0x000000010b1cb89e _PyEval_EvalCodeWithName + 414
        18  python                              0x000000010b09b7c7 _PyFunction_FastCallDict + 231
        19  python                              0x000000010b1d8130 _PyEval_EvalFrameDefault + 46688
        20  python                              0x000000010b1cb89e _PyEval_EvalCodeWithName + 414
        21  python                              0x000000010b09b7c7 _PyFunction_FastCallDict + 231
        22  python                              0x000000010b11dbe1 slot_tp_init + 193
        23  python                              0x000000010b127ce1 type_call + 241
        24  python                              0x000000010b09c4f3 _PyObject_FastCallKeywords + 179
        25  python                              0x000000010b1da2b5 call_function + 453
        26  python                              0x000000010b1d7fb8 _PyEval_EvalFrameDefault + 46312
        27  python                              0x000000010b1cb89e _PyEval_EvalCodeWithName + 414
        28  python                              0x000000010b09ca03 _PyFunction_FastCallKeywords + 195
        29  python                              0x000000010b1da1a7 call_function + 183
        30  python                              0x000000010b1d6f27 _PyEval_EvalFrameDefault + 42071
        31  python                              0x000000010b1cb89e _PyEval_EvalCodeWithName + 414
        32  python                              0x000000010b09ca03 _PyFunction_FastCallKeywords + 195
        33  python                              0x000000010b1da1a7 call_function + 183
        34  python                              0x000000010b1d6f27 _PyEval_EvalFrameDefault + 42071
        35  python                              0x000000010b09c2d5 function_code_fastcall + 117
        36  python                              0x000000010b11dbe1 slot_tp_init + 193
        37  python                              0x000000010b127ce1 type_call + 241
        38  python                              0x000000010b09c4f3 _PyObject_FastCallKeywords + 179
        39  python                              0x000000010b1da2b5 call_function + 453
        40  python                              0x000000010b1d7eff _PyEval_EvalFrameDefault + 46127
        41  python                              0x000000010b1cb89e _PyEval_EvalCodeWithName + 414
        42  python                              0x000000010b22f110 PyRun_FileExFlags + 256
        43  python                              0x000000010b22e587 PyRun_SimpleFileExFlags + 391
        44  python                              0x000000010b25c203 pymain_main + 9635
        45  python                              0x000000010b06ed8d main + 125
        46  libdyld.dylib                       0x00007fff67f42cc9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6

I seem to recall specific requirements regarding the order of initialisation of wx and Panda on macOS. Could you try setting want-wx true in Config.prc? I think that should tell ShowBase to initialise it in the right order.

Oh, yep, that did it! I had thought I was setting that config value previously, but (dumb mistake), I was setting it in a Config.prc file in a different conda environment!

I also had to run the script with pythonw, though, for anyone else who might read this thread.

Btw, is there some way I can point panda3d to a different Config.prc file? I’d like to include one in my repo, rather than have to edit the one in site-packages.

You can use loadPrcFile (imported directly from panda3d.core) in your application to load a .prc file from any desired location. You can also set variables programmatically using loadPrcFileData.