Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Issue with inheritance
#1
Hi All,

I have inherited some code and am in the process of familiarizing myself with it I have gotten stuck. When Trying to the run the code I get the following exception:

2018-10-04 13:16:40 [ERROR ] milkhub.py line:388 unhandledExceptionHandler Unhandled exception occurred:
2018-10-04 13:16:40 [ERROR ] milkhub.py line:389 unhandledExceptionHandler Type: <type 'exceptions.TypeError'>
2018-10-04 13:16:40 [ERROR ] milkhub.py line:390 unhandledExceptionHandler Value: C++ object is not yet constructed, or already destructed.
2018-10-04 13:16:40 [ERROR ] milkhub.py line:393 unhandledExceptionHandler Stack trace: File "milkhub.py", line 415, in <module>

File "/home/daniel/milkhub-dev/MILKHUBGUI/2.5/src/gui/overlays.py", line 170, in __init__
self.name = name


Starting at the 'top':
# initialise pixel2d
GuiManager.pixel2d = overlays.PixelNode(app, "g2d")
the __init__ function:
class PixelNode(OverlayContainer, NodePath):
    # class variables
    app = None
    def __init__(self, app, name=None, parent=None):
        PixelNode.app = app
        OverlayContainer.__init__(self, name)
        NodePath.__init__(self, self.name)
        if parent is None:
            parent = PixelNode.app.render2d
        self.node = self
        self.reparentTo(parent)
        self.setPos(-1,0,1) #the upper left corner
        self.aspectRatioChanged()
which finally calls the __init__ function that throws the exception:
class OverlayContainer(object):
    def __init__(self, name=None, noNode=False, flip=False):
        if name is None:
            name = '%s%i' % (self.__class__.__name__, id(self))
        [b]self.name = name[/b]
        self.node = None if noNode else NodePath(self.name)
        self.x, self.y = 0, 0
        self.zIndex = 0
        self.xScale, self.yScale = 1, 1
        self.flip = flip
        self.yMult = -1 if flip else 1
        if self.node is not None:
            self.node.setScale(self.xScale, 1, self.yScale*self.yMult)
            self.node.setBin('fixed', self.zIndex)
I have no idea why this is happening. If I replace self.name with self.name2 the script will work and throw an exception on the following line "self.node ..."

If anyone has any insights it would be very much appreciated.
Reply
#2
Quote:I have inherited some code
Is that the same as forces upon you?
Quote:Starting at the 'top':
Looks like top should show more code.
Is it possible to show the entire code and verbatim error traceback.
At least name the imports.
Reply
#3
Correct. I will post the additional code but omit the function definitions that aren't of interest for readability sake.

Additional information:

2018-10-04 13:16:40 [ERROR ] milkhub.py line:393 unhandledExceptionHandler Stack trace: File "milkhub.py", line 415, in <module>
main()
File "milkhub.py", line 410, in main
application = MilkhubMain(opts.ip, int(opts.instance))
File "milkhub.py", line 186, in __init__
GuiManager.initialise(self)
File "/home/daniel/milkhub-dev/MILKHUBGUI/2.5/src/gui/guicore.py", line 418, in initialise
GuiManager.pixel2d = overlays.PixelNode(app, "g2d")
File "/home/daniel/milkhub-dev/MILKHUBGUI/2.5/src/gui/overlays.py", line 266, in __init__
OverlayContainer.__init__(self, name)
File "/home/daniel/milkhub-dev/MILKHUBGUI/2.5/src/gui/overlays.py", line 170, in __init__
self.name = name

2018-10-05 08:17:55 [INFO ] milkhub.py line:247 destroy Program exited gracefully.

From top of milkhub.py
#!/usr/bin/env python
import re
import os
import sys
import traceback
import logging
import signal
import optparse
import tempfile
from subprocess import Popen, PIPE

import demoSettings as settings

# Setup the logger as early as possible
logger = logging.getLogger("MHGUI")
logger.setLevel(settings.LOGGING_LEVEL)
streamHandler = logging.StreamHandler(sys.stdout)
streamHandler.setLevel(settings.LOGGING_LEVEL)
logFormatter = logging.Formatter(
    "%(asctime)s [%(levelname)-7s] %(filename)-22s line:%(lineno)-5d %(funcName)-35s %(message)s", "%Y-%m-%d %H:%M:%S"
)
streamHandler.setFormatter(logFormatter)
logger.addHandler(streamHandler)

from direct.showbase import ShowBase
from panda3d.core import ClockObject, loadPrcFileData, PandaSystem

from demoFunctions import ReadKeys
from gui import GuiManager
from gui.panels import HeaderPanels
from gui.controls import preCacheWebkit    # Part of the HtmlPage control
from network import CommsHandlerC
from dataModel import dataModelC
from dialogControlSM import dialogControlSMC
from rotary3d import rotary3dC
from herringbone2d import herringbone2dC
from cameraManager import cameraManagerC
from overallState import overallStateC
from profiler import Profiler
class MilkhubMain(ShowBase.ShowBase):

    def __init__(self, ipAddress, instanceId, *args, **kwargs):
        """
        Milkhub GUI main application class constructor.
        """
        # Set up the exception handler
        sys.excepthook = self.unhandledExceptionHandler
        
        # Start with blank objects
        self.commsHandler = None
        self.dataModel = None
        self.rotary3d = None
        self.herringbone2d = None
        self.keypadSM = None
        self.cameraManager = None
        self.overallState = None

        # Limit FPS
        #noinspection PyArgumentList
        self.globalClock = ClockObject.getGlobalClock()  # we need this elsewhere too
        if settings.LIMIT_FPS:
            self.globalClock.setMode(ClockObject.MLimited)
            self.globalClock.setFrameRate(settings.LIMIT_FPS)

        # Detect the current screen resolutions and update the PRC data, so the app won't crash on
        # Panda3D 1.7 and up if the screen resolution from demoSettings.py could not be set because
        # the monitor could not handle that resolution.
        screens = self.get_screen_settings()
        logger.info("Screen 1 resolution = %dx%d" % (screens[0][0], screens[0][1]))
        if len(screens) > 1:
            logger.info("Screen 2 resolution = %dx%d" % (screens[1][0], screens[1][1]))

        # Panda3D 1.6 doesn't require you give a screen resolution when switching to full screen on Linux, as it
        # didn't support different full screen resolutions (yet) and always used the current resolution for full
        # screen.  Panda3D 1.7 and 1.8 however, support different resolutions for full screen, which is why we
        # must give it a win-size with the resolution we just detected when switching to full screen.
        #noinspection PyArgumentList
        if not PandaSystem.getVersionString().startswith("1.6") and settings.USE_PRODUCTION_PRC:
            loadPrcFileData("", "win-size %d %d" % (screens[0][0], screens[0][1]))

        # Xinerama workaround on Intel video cards only.  If a window is created with fullscreen on, it seems to
        # always use the second screen, so both GUI instances end up on the second screen, which is no good.
        # As a workaround, we turn off fullscreen, manually place both windows, and disable the window decoration,
        # this will give a fake full screen.
        if settings.USE_XINERAMA_HACK and settings.USE_PRODUCTION_PRC:
            if "intel" in self.get_video_card().lower():
                if instanceId == 1:
                    #noinspection PyStringFormat
                    loadPrcFileData("", """
                        fullscreen 0
                        win-size %d %d
                        win-origin %d %d
                        undecorated 1
                    """ % screens[0])
                elif instanceId == 2:
                    #noinspection PyStringFormat
                    loadPrcFileData("", """
                        fullscreen 0
                        win-size %d %d
                        win-origin %d %d
                        undecorated 1
                    """ % screens[1])

        # store ip address and instance id
        self.ipAddress = ipAddress
        self.instanceId = instanceId

        # call parent class constructor (this will create the main window)
        ShowBase.ShowBase.__init__(self, *args, **kwargs)

        # create the debug console (press F12 to open)
        if settings.DEBUG_CONSOLE_ENABLE:
            self.console = DeveloperConsole(self)
            if settings.DEBUG_CONSOLE_AUTO_OPEN:
                self.console.show()
            self.accept("f12-up", self.console.toggle)

            # if we want to show logger messages on the console, we create a new StreamHandler to the new sys.stdout
            # that is "reprogrammed" by console.py
            if settings.DEBUG_CONSOLE_LOGGER:
                consoleHandler = logging.StreamHandler(sys.stdout)
                consoleHandler.setLevel(settings.LOGGING_LEVEL)

                # since we can't fit much on the console, we need a simpler formatter
                consoleFormatter = logging.Formatter(
                "%(asctime)s \1%(levelname)s\1[%(levelname)s]\2 - %(filename)s(%(lineno)d) - %(funcName)s - %(message)s",
                "%H:%M:%S")

                consoleHandler.setFormatter(consoleFormatter)
                logger.addHandler(consoleHandler)
        else:
            self.console = None

        # if DEBUG_TASKS is enabled, open the task manager debugger window
        if settings.DEBUG_TASKS:
            self.taskMgr.popupControls()
		
        # initialise the 2D GUI
        
        GuiManager.initialise(self)
        

        # set name of our process (linux only)
        self.set_proc_name("milkhub-gui-%d" % instanceId)

        # start to webkit2png server
        if sys.platform != "win32" and instanceId == 1:
            if os.path.exists("webkit2png.py"):
                self.webkit2png = Popen(["python", "webkit2png.py"])
            else:
                #noinspection PyArgumentList
                if PandaSystem.getMinorVersion() == 6:
                    self.webkit2png = Popen(["python2.6", "webkit2png.pyc"])
                else:
                    self.webkit2png = Popen(["python2.7", "webkit2png.pyc"])
            preCacheWebkit(self)
        else:
            self.webkit2png = None

        # start the profiler
        if settings.SAVE_PROFILER_CSV:
            csvPath = os.path.join(tempfile.gettempdir(), "milkhub-gui-%d.csv" % instanceId)
        else:
            csvPath = None
        self.profiler = Profiler(self, csvPath)

        # setup our main objects
        if settings.USE_DB:
            self.db = MilkhubDB()
        else:
            self.db = None

        self.commsHandler = CommsHandlerC(self)
        self.dataModel = dataModelC(self)

        # pre-generate 2D screens to reduce stutter when switching to each screen the first time
        self.headerPanels = HeaderPanels(self)

        self.rotary3d = rotary3dC(self)
        self.herringbone2d = herringbone2dC(self)
        self.keypadSM = dialogControlSMC(self)
        self.cameraManager = cameraManagerC(self, initialView="SPLIT_SCREEN_SIDE")
        self.overallState = overallStateC(self)

        # enter idle state
        self.keypadSM.request("IdleState")

        # setup keyboard handler for testing
        self.keys = ReadKeys(self)

        # register our signal handler to receive SIGTERM
        signal.signal(signal.SIGTERM, self.signal_handler)
def main():

	parser = optparse.OptionParser()
	parser.add_option("-i", "--instance", default=1, help="GUI instance 1 or 2 (defaults to 1)")
	parser.add_option("-a", "--ip", default="127.0.0.1", help="IP address of Milkhub App (defaults to localhost)")
	(opts, args) = parser.parse_args()
	application = MilkhubMain(opts.ip, int(opts.instance))
	
	application.run()

if __name__ == "__main__":
    main()
This is the class which has the initialise function called above.

import os
import sys
import math
import logging
import tempfile
from shutil import copyfile

from panda3d.core import TextProperties, TextPropertiesManager, Point3
from direct.interval.IntervalGlobal import Sequence, LerpFunc, Wait, Func
from direct.showbase import DirectObject
from direct.gui.DirectGui import DirectFrame

import overlays
from color import Color
from milkhubKeys import keyCodes
import demoSettings as settings

class GuiManager(DirectObject.DirectObject):
    # assets URL (passed to Jinja templates as a template variable {{ assets }}
    ASSETS_PATH = os.path.abspath(os.path.join(__file__, "..", "..", "assets"))
    ASSETS_URL = ASSETS_PATH.replace("\\", "/")
    if ASSETS_URL.startswith("/"):
        #noinspection PyAugmentAssignment
        ASSETS_URL = "file://" + ASSETS_URL
    else:
        #noinspection PyAugmentAssignment
        ASSETS_URL = "file:///" + ASSETS_URL

    # gui images
    LOGO = "assets/Logos/milkhub_logo.png"
    TRUTEST_LOGO = "assets/Logos/trutest_logo.png"
    DRAFTING_ICON = "assets/Black Overlays/icons/drafting-screen-icon.png"
    CLEANING_ICON = "assets/Black Overlays/icons/cleaning-screen-icon.png"
    CLEANING_SUMMARY_ICON = "assets/Black Overlays/icons/cleaning-summary-icon.png"
    MILKING_ICON = "assets/Black Overlays/icons/milking-screen-icon.png"
    EVENT_ICON = "assets/Black Overlays/icons/event-screen-icon.png"
    GENERAL_ICON = "assets/Black Overlays/icons/general-screen-icon.png"
    PLANT_ICON = "assets/Black Overlays/icons/plant-screen-icon.png"
    PANELBG_LEFT = "assets/Keypad/keypadBKG_L.png"
    PANELBG_RIGHT = "assets/Keypad/keypadBKG_R.png"
    PANELBG_LARGE_LEFT = "assets/Summary Event/CowRecordBKG-left.png"
    PANELBG_LARGE_RIGHT = "assets/Summary Event/CowRecordBKG-right.png"
    SIDEBAR_1CAM_LEFT = "assets/Milking Screen/Sidebars/Sidebar_backdrop_L.png"
    SIDEBAR_1CAM_RIGHT = "assets/Milking Screen/Sidebars/Sidebar_backdrop_R.png"
    SIDEBAR_2CAM_LEFT = "assets/Milking Screen/Sidebars/Sidebar_backdrop_2cam_L.png"
    SIDEBAR_2CAM_RIGHT = "assets/Milking Screen/Sidebars/Sidebar_backdrop_2cam_R.png"
    CHECK = "assets/Keypad/other/tickbox_tick.png"
    NOCHECK = "assets/Keypad/other/tickbox_no_tick.png"
    ENTER = "assets/Keypad/keypad_bttns/enter.png"
    NUMENTRY_BG = "assets/Keypad/other/cow_bail_num_input_bkg.png"
    NUMENTRY_PICKER = "assets/Keypad/other/picker_arrows.png"
    SELECTOR = (
        "assets/Keypad/other/selector_L.png",
        "assets/Keypad/other/selector_C.png",
        "assets/Keypad/other/selector_R.png",
    )
    SCROLL_UP = "assets/Keypad/other/up_arrow.png"
    SCROLL_DOWN = "assets/Keypad/other/down_arrow.png"
    DRAFT_LEFT = "assets/Milking Screen/Tile/Draft/draft_arrow2_L.png"
    DRAFT_RIGHT = "assets/Milking Screen/Tile/Draft/draft_arrow2_R.png"
    GRAPH_INSIDE = "assets/Milking Screen/Tile/Content/graph_inside.png"
    MILKING_GRAPH = "assets/Milking Screen/Tile/Content/graph_outline.png"
    CLEANING_GRAPH = "assets/Cleaning and Plant Screens/loading_bar.png"
    SUCCESS_TICK = "assets/Milking Screen/Sidebars/success.png"
    ERROR_ICON = "assets/Milking Screen/Sidebars/error.png"
    BLANK_GROUP = "assets/Milking Screen/Tile/Groups/blankgroup.png"

    PLATE_LEFT = "assets/Cleaning and Plant Screens/info_bkg_L.png"
    PLATE_RIGHT = "assets/Cleaning and Plant Screens/info_bkg_R.png"
    PLATE_CENTER = "assets/Cleaning and Plant Screens/info_bkg_C.png"
    TEMPERATURE_PANEL = "assets/Cleaning and Plant Screens/tempBKGclear.png"
    GENERAL_SMALL_BKG = "assets/Summary General/small_BKG.png"
    GENERAL_MEDIUM_BKG = "assets/Summary General/medium_BKG.png"
    GENERAL_LARGE_BKG = "assets/Summary General/large_BKG.png"
    GENERAL_GRAPH_BKG = "assets/Summary General/graph_BKG.png"
    ALERT_ICON = "assets/Milking Screen/Tile/Alerts/blank.png"
    ALERT_ICON_BG = "assets/Milking Screen/Tile/Alerts/alert-bg.png"
    ALERT_ICON_FRAME = "assets/Milking Screen/Tile/Alerts/alert-frame.png"
    BLANK_IMAGE = "assets/General/blank.png"
    BAIL_TEXTURE = "assets/models/textures/metal_texture.jpg"
    POPUP_MESSAGE_BKG = "assets/General/popupMessage.png"

    # drafting screen
    DRAFT_PLATE = "assets/Drafting Screen/draftplate.png"
    
    HB_MILKING_PLATE = "assets/Milking Screen/hb_plate.png"

    # menu icons
    MENU_BLANK = "assets/Keypad/menu_keypad_bttns/blank_key.png"
    MENU_1 = "assets/Keypad/menu_keypad_bttns/numpad_1.png"
    MENU_2 = "assets/Keypad/menu_keypad_bttns/numpad_2.png"
    MENU_3 = "assets/Keypad/menu_keypad_bttns/numpad_3.png"
    MENU_4 = "assets/Keypad/menu_keypad_bttns/numpad_4.png"
    MENU_5 = "assets/Keypad/menu_keypad_bttns/numpad_5.png"
    MENU_6 = "assets/Keypad/menu_keypad_bttns/numpad_6.png"
    MENU_7 = "assets/Keypad/menu_keypad_bttns/numpad_7.png"
    MENU_8 = "assets/Keypad/menu_keypad_bttns/numpad_8.png"
    MENU_9 = "assets/Keypad/menu_keypad_bttns/numpad_9.png"
    MENU_0 = "assets/Keypad/menu_keypad_bttns/numpad_0.png"
    MENU_BAIL = "assets/Keypad/menu_keypad_bttns/bail.png"
    MENU_EARTAG = "assets/Keypad/menu_keypad_bttns/eartag.png"
    MENU_UP = "assets/Keypad/menu_keypad_bttns/up_arrow.png"
    MENU_DOWN = "assets/Keypad/menu_keypad_bttns/down_arrow.png"
    MENU_OTHER = "assets/Keypad/menu_keypad_bttns/other.png"
    MENU_MAST = "assets/Keypad/menu_keypad_bttns/mast.png"
    MENU_FOOT = "assets/Keypad/menu_keypad_bttns/foot.png"
    MENU_TREAT = "assets/Keypad/menu_keypad_bttns/treat.png"
    MENU_AB = "assets/Keypad/menu_keypad_bttns/ab.png"
    MENU_PD = "assets/Keypad/menu_keypad_bttns/pd.png"
    MENU_SHIFT = "assets/Keypad/menu_keypad_bttns/shift.png"
    MENU_SYSTEM = "assets/Keypad/menu_keypad_bttns/system.png"
    MENU_CLEAR = "assets/Keypad/menu_keypad_bttns/clear.png"
    MENU_ENTER = "assets/Keypad/menu_keypad_bttns/enter.png"
    PULLCORD = "assets/Keypad/pullcord.png"

    # keypad
    KEYPAD = "assets/Keypad/keypad_blank.png"
    KEYPAD_1 = "assets/Keypad/keypad_bttns/numpad_1.png"
    KEYPAD_2 = "assets/Keypad/keypad_bttns/numpad_2.png"
    KEYPAD_3 = "assets/Keypad/keypad_bttns/numpad_3.png"
    KEYPAD_4 = "assets/Keypad/keypad_bttns/numpad_4.png"
    KEYPAD_5 = "assets/Keypad/keypad_bttns/numpad_5.png"
    KEYPAD_6 = "assets/Keypad/keypad_bttns/numpad_6.png"
    KEYPAD_7 = "assets/Keypad/keypad_bttns/numpad_7.png"
    KEYPAD_8 = "assets/Keypad/keypad_bttns/numpad_8.png"
    KEYPAD_9 = "assets/Keypad/keypad_bttns/numpad_9.png"
    KEYPAD_0 = "assets/Keypad/keypad_bttns/numpad_0.png"
    KEYPAD_BAIL = "assets/Keypad/keypad_bttns/bail.png"
    KEYPAD_EARTAG = "assets/Keypad/keypad_bttns/eartag.png"
    KEYPAD_UP = "assets/Keypad/keypad_bttns/up_arrow.png"
    KEYPAD_DOWN = "assets/Keypad/keypad_bttns/down_arrow.png"
    KEYPAD_OTHER = "assets/Keypad/keypad_bttns/other.png"
    KEYPAD_MAST = "assets/Keypad/keypad_bttns/mast.png"
    KEYPAD_FOOT = "assets/Keypad/keypad_bttns/foot.png"
    KEYPAD_TREAT = "assets/Keypad/keypad_bttns/treat.png"
    KEYPAD_AB = "assets/Keypad/keypad_bttns/ab.png"
    KEYPAD_PD = "assets/Keypad/keypad_bttns/pd.png"
    KEYPAD_SHIFT = "assets/Keypad/keypad_bttns/shift.png"
    KEYPAD_SYSTEM = "assets/Keypad/keypad_bttns/system.png"
    KEYPAD_CLEAR = "assets/Keypad/keypad_bttns/clear.png"
    KEYPAD_ENTER = "assets/Keypad/keypad_bttns/enter.png"

    # cleaning screen
    CLEANING_LEGEND = "assets/Cleaning and Plant Screens/cleaningScreenlegend.png"
    CLEANING_LEGEND_BAR = "assets/Cleaning and Plant Screens/cleaningScreenlegendColourBar.png"
    CLEANING_LEFT_BACKGROUND = "assets/Cleaning and Plant Screens/cleaningScreenLeftBKG.png"
    CLEANING_LEFT_AVGTEMP = "assets/Cleaning and Plant Screens/cleaningScreenBlackBoxText.png"
    CLEANING_DEGREES = "assets/Cleaning and Plant Screens/cleaningScreenDegrees.png"
    CLEANING_FILLER_L = "assets/Cleaning and Plant Screens/cleaningFiller_L.png"
    CLEANING_FILLER_R = "assets/Cleaning and Plant Screens/cleaningFiller_R.png"

    # animations
    KEYPRESS_ANIM = ["assets/Keypad/key_presses/keypad_%s.png" % str(frame).zfill(5) for frame in range(15)]
    CLEANING_ANIM = ["assets/Cleaning and Plant Screens/loader%d.png" % frame for frame in range(9)]

    # key to keypad icon lookup table
    keypadIcon = {
        keyCodes.KEY_ONE: KEYPAD_1,
        keyCodes.KEY_TWO: KEYPAD_2,
        keyCodes.KEY_THREE: KEYPAD_3,
        keyCodes.KEY_FOUR: KEYPAD_4,
        keyCodes.KEY_FIVE: KEYPAD_5,
        keyCodes.KEY_SIX: KEYPAD_6,
        keyCodes.KEY_SEVEN: KEYPAD_7,
        keyCodes.KEY_EIGHT: KEYPAD_8,
        keyCodes.KEY_NINE: KEYPAD_9,
        keyCodes.KEY_ZERO: KEYPAD_0,
        keyCodes.KEY_BAIL: KEYPAD_BAIL,
        keyCodes.KEY_TAG: KEYPAD_EARTAG,
        keyCodes.KEY_UP: KEYPAD_UP,
        keyCodes.KEY_DOWN: KEYPAD_DOWN,
        keyCodes.KEY_OTHER: KEYPAD_OTHER,
        keyCodes.KEY_MAST: KEYPAD_MAST,
        keyCodes.KEY_FOOT: KEYPAD_FOOT,
        keyCodes.KEY_TREAT: KEYPAD_TREAT,
        keyCodes.KEY_AB: KEYPAD_AB,
        keyCodes.KEY_PD: KEYPAD_PD,
        keyCodes.KEY_SHIFT: KEYPAD_SHIFT,
        keyCodes.KEY_SYSTEM: KEYPAD_SYSTEM,
        keyCodes.KEY_CLEAR: KEYPAD_CLEAR,
        keyCodes.KEY_ENTER: KEYPAD_ENTER
    }

    # key to menu icon lookup table
    menuIcon = {
        None: MENU_BLANK,
        keyCodes.KEY_ONE: MENU_1,
        keyCodes.KEY_TWO: MENU_2,
        keyCodes.KEY_THREE: MENU_3,
        keyCodes.KEY_FOUR: MENU_4,
        keyCodes.KEY_FIVE: MENU_5,
        keyCodes.KEY_SIX: MENU_6,
        keyCodes.KEY_SEVEN: MENU_7,
        keyCodes.KEY_EIGHT: MENU_8,
        keyCodes.KEY_NINE: MENU_9,
        keyCodes.KEY_ZERO: MENU_0,
        keyCodes.KEY_BAIL: MENU_BAIL,
        keyCodes.KEY_TAG: MENU_EARTAG,
        keyCodes.KEY_UP: MENU_UP,
        keyCodes.KEY_DOWN: MENU_DOWN,
        keyCodes.KEY_OTHER: MENU_OTHER,
        keyCodes.KEY_MAST: MENU_MAST,
        keyCodes.KEY_FOOT: MENU_FOOT,
        keyCodes.KEY_TREAT: MENU_TREAT,
        keyCodes.KEY_AB: MENU_AB,
        keyCodes.KEY_PD: MENU_PD,
        keyCodes.KEY_SHIFT: MENU_SHIFT,
        keyCodes.KEY_SYSTEM: MENU_SYSTEM,
        keyCodes.KEY_CLEAR: MENU_CLEAR,
        keyCodes.KEY_ENTER: MENU_ENTER
    }

    # These class variables get set when initialise() is called
    app = None
    dummy_overlay = None
    pixel2d = None
    width = 0
    height = 0
    screenWidth = 0
    screenHeight = 0
    oldScreenWidth = None
    oldScreenHeight = None
    resolutionChanged = False
    flashPopup = None
    flashPopupLerp = None
    bulletinMessagePanel = None
    bulletinMessageLerp = None

    # Legacy constants, no longer used by the 2D gui, but still in 3D, these get set after initialise() is called
    FONT_BOLD_HIRES = None
    FONT_BOLD_HIRES_OUTLINE = None

    @staticmethod
    def initialise(app, width=1920, height=1080):
        """
        Initialises the :data:`gui.GuiManager` class, this is called once when the application first starts,
        and should be called before we do any GUI operations.

        The ``width`` and ``height`` parameters are not the actual screen resolution the application is running at,
        but rather the desired resolution for the GUI controls, the controls will scale to the actual real screen
        resolution, but coordinates are still in the "desired" screen resolution defined by ``width`` and ``height``.

        For the Milkhub GUI the desired resolution is always 1920x1080 and shouldn't really be changed, or things
        will generally look all wrong, or zoomed in.
        """
        GuiManager.app = app
        GuiManager.setDesiredResolution(width, height)
        GuiManager.resolutionChanged = False  # not wanted on first run, only when window resizes

        # initialise pixel2d
        GuiManager.pixel2d = overlays.PixelNode(app, "g2d")
        GuiManager.pixel2d.controls = []
        GuiManager.pixel2d.getContainer = lambda: GuiManager.pixel2d
        

        # the dummy overlay is used to "hide" elements, by reparenting them to the dummy overlay
        GuiManager.dummy_overlay = overlays.Overlay()

        # Store the current and old screen width and height. This is used by Font.resizeFont() to bypass a memory leak
        # in Panda3D 1.6.  We store the old window width and height, so we only resize the fonts if the window is
        # actually resized, but not when we are in full screen.  The only downside is, that, if you resize the window,
        # it will still leak memory, but if you run it in full screen as it is in the farm, or don't resize the window
        # too often it's fine.
        GuiManager.screenWidth = float(GuiManager.app.win.getXSize())
        GuiManager.screenHeight = float(GuiManager.app.win.getYSize())
        GuiManager.oldScreenWidth = GuiManager.screenWidth
        GuiManager.oldScreenHeight = GuiManager.screenHeight

        # adds some text properties so you can make part of a text label Milkhub gold
        GuiManager.setupTextProperties()

        # initialise font manager
        Font.initialise()

        # create some font constants to be used in the 3D world only, compatible with the old font system
        # that we originally used in the 2D GUI until we changed all that.
        GuiManager.FONT_BOLD_HIRES = Font.loadFont(Font.BOLD, 150)
        GuiManager.FONT_BOLD_HIRES_OUTLINE = Font.loadFont(Font.BOLD, 150, outline=(Color.BLACK, 0.5, 0.4))

        # initialise our aspectRatioChanged handler
        GuiManager.app.accept("aspectRatioChanged", GuiManager.aspectRatioChanged)

        # create popup message boxes
        GuiManager.createFlashPopup()
        GuiManager.playingFlashMessage = False
        GuiManager.flashMessageQueue = []

        # create a large black frame to blackout the whole screen as a hack to "turn the display off"
        GuiManager.blackOutFrame = DirectFrame(frameColor=Color.BLACK, frameSize=(-2, 2, -1, 1), pos=(0, 0, 0))
        GuiManager.blackOutFrame.hide()
        GuiManager.screenBlackedOut = False

        #
        from panels.basic import BasicPanel
        from controls.labels import Label
        GuiManager.bulletinMessagePanel = BasicPanel(
            GuiManager.pixel2d,      # parent node
            size=(1920, 55),
            pos=(0, 1080),
            color=Color.WHITE,
            zIndex=200
        )
        GuiManager.bulletinMessagePanel.caption = Label(
            GuiManager.bulletinMessagePanel,   # parent node
            pos=(960, 5),
            caption="",
            fontSize=Font.SIZE_MEDIUM,
            color=Color.BLACK,
            align=Position.CENTER
        )
Reply
#4
Could you give a brief description of what this is supposed to do? I'm confused because I see panda3d (a 3d game engine), graphics drivers initialization, but then also django/jinja templating, which is for web servers rendering html.

There's also controller handling, so is it a game that connects to a remote host, and ALSO is that same remote host sometimes?

Would you be able to upload everything to github or something, so we can see the full structure and try to run it ourselves?
Reply
#5
The ultimate error occurs in the overlays module according to the traceback. I noticed that the Milkhub class passes itself to the GUIManager which, in turn, passes the Milkhub instance to overlays.PixelNode() as the argument "app". Could you post the PixelNode function or __init__ method? That's the next breadcrumb. It evidently attempts to create an OverlayContainer which does not approve of the argument passed for "name".
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020