Home > Net >  Pass Wx Frame class as a variable to another Class
Pass Wx Frame class as a variable to another Class

Time:05-11

I am trying to pass a WX frame class to another class. I have three py files which are as follows:

gui_20220510.py - this contains the gui code

import wx

class Frame_Demo(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: Frame_Demo.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((400, 300))

        self.panel_1 = wx.Panel(self, wx.ID_ANY)

        sizer_1 = wx.BoxSizer(wx.VERTICAL)

        self.notebook_1 = wx.Notebook(self.panel_1, wx.ID_ANY)
        sizer_1.Add(self.notebook_1, 1, wx.EXPAND, 0)

        self.notebook_1_pane_1 = wx.Panel(self.notebook_1, wx.ID_ANY)
        self.notebook_1.AddPage(self.notebook_1_pane_1, "notebook_1_pane_1")

        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)

        label_1 = wx.StaticText(self.notebook_1_pane_1, wx.ID_ANY, "This is Test: ")
        sizer_2.Add(label_1, 0, 0, 0)

        self.text_ctrl_1 = wx.TextCtrl(self.notebook_1_pane_1, wx.ID_ANY, "Type")
        sizer_2.Add(self.text_ctrl_1, 0, 0, 0)

        self.notebook_1_pane_2 = wx.Panel(self.notebook_1, wx.ID_ANY)
        self.notebook_1.AddPage(self.notebook_1_pane_2, "notebook_1_pane_2")

        sizer_3 = wx.BoxSizer(wx.VERTICAL)

        sizer_3.Add((0, 0), 0, 0, 0)

        self.notebook_1_pane_2.SetSizer(sizer_3)

        self.notebook_1_pane_1.SetSizer(sizer_2)

        self.panel_1.SetSizer(sizer_1)

        self.Layout()

demo.py - This contains the run functions to import the wx frame

from importlib import import_module
from wx import App

global Frame_Demo
global builddate

class Demo_Main(Frame_Demo):
    def __init__(self, *args, **kwds):
        Frame_Demo.__init__(self, *args, **kwds)
        # Update the Frame Title to Reflect Build Date
        self.SetTitle('Demo Tool v'   builddate)
        self.Maximize(True)

def main_run(bdate, gui_version):
    global builddate
    global Frame_Demo
    builddate = bdate
    gui_module = import_module('gui_'   gui_version)
    Frame_Demo = gui_module.Frame_Demo
    app = App()
    frame = Demo_Main(None)
    frame.Show()
    app.MainLoop()

Main.py - This is the main file to run the program

from demo import main_run

builddate = '2022-MAY-10'
gui_version = '20220510'

if __name__ == '__main__':
    main_run(builddate, gui_version)

When trying to run main.py, I am getting "Frame_Demo" is not defined error even though it was defined as a global.

What am I doing wrong here? any guidance is much appreciated. Thanks in advance.

CodePudding user response:

Word global is NOT for creating global variables. All variables created outside functions are automtically global (inside current module) but you have to assign value to variable to create it.

We use global inside function to inform function that when we use = to assign new value to variable then it has to use external/global variable instead of creating local one.

So you have to import Frame_Demo before you define class Demo_Main(Frame_Demo):. Or you have to define this class inside main_run, after Frame_Demo = gui_module.Frame_Demo

from importlib import import_module
from wx import App

def main_run(builddate, gui_version):

    gui_module = import_module('gui_'   gui_version)
    Frame_Demo = gui_module.Frame_Demo

    class Demo_Main(Frame_Demo):
        def __init__(self, *args, **kwds):
            super().__init__(*args, **kwds)
            # Update the Frame Title to Reflect Build Date
            self.SetTitle('Demo Tool v'   builddate)
            self.Maximize(True)

    app = App()
    frame = Demo_Main(None)
    frame.Show()
    app.MainLoop()

EDIT:

You could also put these value in separated file - ie. settings.py

builddate = '2022-MAY-10'
gui_version = '20220511'

and import it to demo.py

from importlib import import_module
from wx import App

import settings

gui_module = import_module('gui_'   settings.gui_version)
Frame_Demo = gui_module.Frame_Demo

class Demo_Main(Frame_Demo):
    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)
        # Update the Frame Title to Reflect Build Date
        self.SetTitle('Demo Tool v'   settings.builddate)
        self.Maximize(True)

def main_run():
    app = App()
    frame = Demo_Main(None)
    frame.Show()
    app.MainLoop()

And run main.py without these values

from demo import main_run

if __name__ == '__main__':
    main_run()
  • Related