Could not open the window error

i have began to follow the book of fireclaw the fox about creating a video game with panda3D, but when I paste his template for main.py, I have this error :

2020-04-21 12:21:01.472 Python[23635:1594988] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to (null)
:04-21-2020 12:21:02 ShowBase(warning): Unable to open 'onscreen' window.
Traceback (most recent call last):
  File "/Users/arthur/Documents/PycharmProjects/TankFighter/game/main.py", line 264, in <module>
    Game = Main()
  File "/Users/arthur/Documents/PycharmProjects/TankFighter/game/main.py", line 85, in __init__
    ShowBase.__init__(self)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/direct/showbase/ShowBase.py", line 289, in __init__
    self.openDefaultWindow(startDirect = False, props=props)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/direct/showbase/ShowBase.py", line 959, in openDefaultWindow
    self.openMainWindow(*args, **kw)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/direct/showbase/ShowBase.py", line 995, in openMainWindow
    self.openWindow(*args, **kw)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/direct/showbase/ShowBase.py", line 742, in openWindow
    raise Exception('Could not open window.')
Exception: Could not open window.

I don’t really understand why because the first time I’ve ran the code, a black window opened as expected, but since this first time, this error comeback every time. I’ve looked for an answer on the forum but I did not found it.

I’m on a Macbook Pro 13", 2017 model, on MacOS Catalina 10.15

thanks for reading,
Arthur

Just to be sure, are you using the latest version of Panda3D (1.10.6)? Both 1.10.6 and 1.10.5 have important Catalina fixes.

well, I was using the 1.10.5 version, so I installed the 10.1.6 (post2) version, and nothing changed :cry:
by the way, I’m on 3.7 python version on PyCharm

Arthur

I wonder if there are some permission issues going on. Hopefully someone more familiar with macOS and the oddities introduced by Catalina can chime in. In the meantime, would you mind posting what your main.py looks like? Might was well do a sanity-check on that.

Yup of course, I give you the code and the launchpad link of the creator

https://bazaar.launchpad.net/~fireclawthefox/panda3dcodecollection/trunk/view/head:/core/template%20for%20main.py

Thanks a lot for your help

Arthur


#!/usr/bin/python
__author__ = "Fireclaw the Fox"
__license__ = """
Simplified BSD (BSD 2-Clause) License.
See License.txt or http://opensource.org/licenses/BSD-2-Clause for more info
"""

# Python imports
import os

# Panda3D imoprts
from direct.showbase.ShowBase import ShowBase
from direct.fsm.FSM import FSM
from direct.gui.DirectGui import DGG
from panda3d.core import (
    AntialiasAttrib,
    ConfigPageManager,
    ConfigVariableInt,
    ConfigVariableBool,
    ConfigVariableString,
    OFileStream,
    WindowProperties,
    loadPrcFileData,
    loadPrcFile,
    Filename)

# Game imports
#TODO: Put your game imports here

#
# PATHS AND CONFIGS
#
# set company and application details
companyName = "Your Companies Name"
appName = "Game Name"
versionstring = "19.07"

# build the path from the details we have
home = os.path.expanduser("~")
basedir = os.path.join(
    home,
    companyName,
    appName)
if not os.path.exists(basedir):
    os.makedirs(basedir)

# look for a config file
prcFile = os.path.join(basedir, "{}.prc".format(appName))
if os.path.exists(prcFile):
    mainConfig = loadPrcFile(Filename.fromOsSpecific(prcFile))

# set configurations that should not be changed from a config file
loadPrcFileData("",
"""
    #
    # Model loading
    #
    model-path $MAIN_DIR/assets/

    #
    # Window and graphics
    #
    window-title {}
    #show-frame-rate-meter 1

    #
    # Logging
    #
    #notify-level info
    notify-timestamp 1
""".format(appName))

#
# MAIN GAME CLASS
#
class Main(ShowBase, FSM):
    """Main function of the application
    initialise the engine (ShowBase)"""

    def __init__(self):
        """initialise the engine"""
        ShowBase.__init__(self)
        base.notify.info("Version {}".format(versionstring))
        FSM.__init__(self, "FSM-Game")

        #
        # BASIC APPLICATION CONFIGURATIONS
        #
        # disable pandas default camera driver
        self.disableMouse()
        # set antialias for the complete sceen to automatic
        self.render.setAntialias(AntialiasAttrib.MAuto)
        # shader generator
        render.setShaderAuto()
        # Enhance font readability
        DGG.getDefaultFont().setPixelsPerUnit(100)
        # get the displays width and height for later usage
        self.dispWidth = self.pipe.getDisplayWidth()
        self.dispHeight = self.pipe.getDisplayHeight()

        #
        # CONFIGURATION LOADING
        #
        # load given variables or set defaults
        # check if particles should be enabled
        # NOTE: If you use the internal physics engine, this always has
        #       to be enabled!
        particles = ConfigVariableBool("particles-enabled", True).getValue()
        if particles:
            self.enableParticles()

        def setFullscreen():
            """Helper function to set the window fullscreen
            with width and height set to the screens size"""
            # set window properties
            # clear all properties not previously set
            base.win.clearRejectedProperties()
            # setup new window properties
            props = WindowProperties()
            # Fullscreen
            props.setFullscreen(True)
            # set the window size to the screen resolution
            props.setSize(self.dispWidth, self.dispHeight)
            # request the new properties
            base.win.requestProperties(props)
            # Set the config variables so we correctly store the
            # new size and fullscreen setting later
            winSize = ConfigVariableString("win-size")
            winSize.setValue("{} {}".format(self.dispWidth, self.dispHeight))
            fullscreen = ConfigVariableBool("fullscreen")
            fullscreen.setValue(True)
            # Render a frame to make sure the fullscreen is applied
            # before we do anything else
            self.taskMgr.step()
            # make sure to propagate the new aspect ratio properly so
            # the GUI and other things will be scaled appropriately
            aspectRatio = self.dispWidth / self.dispHeight
            self.adjustWindowAspectRatio(aspectRatio)


        # check if the config file hasn't been created
        if not os.path.exists(prcFile):
            setFullscreen()
        # automatically safe configuration at application exit
        base.exitFunc = self.__writeConfig

        #
        # INITIALIZE GAME CONTENT
        #
        #TODO: put game content initialization here

        #
        # EVENT HANDLING
        #
        # By default we accept the escape key
        self.accept("escape", self.__escape)

        #
        # ENTER GAMES INITIAL FSM STATE
        #
        #TODO: Change this to any state you want the game to start with
        self.request("Game")

    #
    # FSM PART
    #

    def enterGame(self):
        # main game logic should be started here
        pass

    def exitGame(self):
        # cleanup for game code
        pass

    #
    # FSM PART END
    #

    #
    # BASIC FUNCTIONS
    #

    def __escape(self):
        """Handle user escape key klicks"""
        if self.state == "Game":
            # In this state, we will stop the application
            self.userExit()
        else:
            # In every other state, we switch back to the Game state
            self.request("Game")

    def __writeConfig(self):
        """Save current config in the prc file or if no prc file exists
        create one. The prc file is set in the prcFile variable"""
        page = None

        #
        #TODO: add any configuration variable names that you have added
        #      to the dictionaries in the next lines. Set the current
        #      configurations value as value in this dictionary and it's
        #      name as key.
        configVariables = {
            # set the window size in the config file
            "win-size": ConfigVariableString("win-size", "{} {}".format(self.dispWidth, self.dispHeight)).getValue(),
            # set the default to fullscreen in the config file
            "fullscreen": "#t" if ConfigVariableBool("fullscreen", True).getValue() else "#f",
            # particles
            "particles-enabled": "#t" if self.particleMgrEnabled else "#f",
            # audio
            "audio-volume": str(round(self.musicManager.getVolume(), 2)),
            "audio-music-active": "#t" if ConfigVariableBool("audio-music-active").getValue() else "#f",
            "audio-sfx-active": "#t" if ConfigVariableBool("audio-sfx-active").getValue() else "#f",
            # logging
            "notify-output": os.path.join(basedir, "game.log"),
            # window
            "framebuffer-multisample": "#t" if ConfigVariableBool("framebuffer-multisample").getValue() else "#f",
            "multisamples": str(ConfigVariableInt("multisamples", 8).getValue()),
            "texture-anisotropic-degree": str(ConfigVariableInt("texture-anisotropic-degree").getValue()),
            "textures-auto-power-2": "#t" if ConfigVariableBool("textures-auto-power-2", True).getValue() else "#f",
            }

        page = None
        # Check if we have an existing configuration file
        if os.path.exists(prcFile):
            # open the config file and change values according to current
            # application settings
            page = loadPrcFile(Filename.fromOsSpecific(prcFile))
            removeDecls = []
            for dec in range(page.getNumDeclarations()):
                # Check if our variables are given.
                # NOTE: This check has to be done to not loose our base
                #       or other manual config changes by the user
                if page.getVariableName(dec) in configVariables.keys():
                    removeDecls.append(page.modifyDeclaration(dec))
            for dec in removeDecls:
                page.deleteDeclaration(dec)
        else:
            # Create a config file and set default values
            cpMgr = ConfigPageManager.getGlobalPtr()
            page = cpMgr.makeExplicitPage("Application Config")

        # always write custom configurations
        for key, value in configVariables.items():
            page.makeDeclaration(key, value)
        # create a stream to the specified config file
        configfile = OFileStream(prcFile)
        # and now write it out
        page.write(configfile)
        # close the stream
        configfile.close()

    #
    # BASIC END
    #
# CLASS Main END

#
# START GAME
#
Game = Main()
Game.run()