How to separate different widgets creation in different files?

Hi, all, I want to separate different widgets creation for my application so that I can manipulate it more easily. For example, I want to create a menu called File, so I create it in a separate file called menu_file.py, I also create a menu_bar.py, a main_frame.py and a main_panel.py like bellow, but it does’t work. I checked all the single components with ChatGPT, but no errors appeared, Can anyone give me some clues?

main_frame.py

import wx
from menu_bar import MenuBar
from main_panel import MainPanel


class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MainFrame, self).__init__(*args, **kwargs)
        self.menu_bar = MenuBar(self)
        self.main_panel = MainPanel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.menu_bar, 0, wx.EXPAND)
        sizer.Add(self.main_panel, 1, wx.EXPAND)
        self.SetSizer(sizer)
        self.SetMenuBar(self.menu_bar)


if __name__ == '__main__':
    app = wx.App()
    frame = MainFrame(parent=None, title="SimpleApp", size=(800, 600))
    frame.Show()
    app.MainLoop()

main_panel.py

import wx


class MainPanel(wx.Panel):
    def __init__(self, parent):
        super(MainPanel, self).__init__(parent)
        self.SetBackgroundColour(wx.Colour(255, 255, 255))  # Set panel background

menu_bar.py

import wx
from menu_file import FileMenu


class MenuBar(wx.MenuBar):
    def __init__(self, parent):
        super(MenuBar, self).__init__()
        file_menu = FileMenu(parent)
        self.Append(file_menu, "File")

menu_file.py

import wx


class FileMenu(wx.Menu):
    def __init__(self, parent):
        super(FileMenu, self).__init__()
        self.Append(wx.ID_OPEN, 'Open')
        self.Append(wx.ID_SAVE, 'Save')

Hi and welcome to Discuss wxPython,

In menu_bar.py you have:

from menu_file import FileMenu

That should be:

from file_menu import FileMenu

After making that change, your code works for me using Python 3.10.12 + wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1 on Linux Mint 21.2

Thank you for your reply, I write a wrong name. But when I changed the name correctly, it still get the error: python3 main_frame.py
Segmentation fault: 11
I don’t know where is the error from?

To get a segmentation fault from such a simple wxPython program suggests there may be something wrong with your python or wxPython installation.

Can you post the full error message?

What operating system are you using?

How did you install wxPython?

my system is macOS Big Sur 11.7.8

Python 3.8.3 (default, Oct 20 2020, 18:11:31)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import wx
wx.__version__
'4.1.1'

#the error is the full, it just shows:
Segmentation fault: 11
I install wxPython from pip I remembered.

I am not familiar with running wxPython on macOS, so I don’t know if those versions have any issues.

If you put all the classes in the same module, does it still fail?

combined.py (1.1 KB)

One thing I have noticed is that you are adding the menubar to the sizer as well as passing it to self.SetMenuBar().

Normally, you just need to pass it to self.SetMenuBar().

Try commenting out the line where you add it to the sizer.

yes, it still fails, but this time, the mac reports more detail errors for the accidentally closed python. however, when I annotate those codes related with menu bar, it works well and just shows me the panel. thank you very much for your effects


import wx

class FileMenu(wx.Menu):
    def __init__(self, parent):
        super(FileMenu, self).__init__()
        self.Append(wx.ID_OPEN, 'Open')
        self.Append(wx.ID_SAVE, 'Save')

class MainPanel(wx.Panel):
    def __init__(self, parent):
        super(MainPanel, self).__init__(parent)
        self.SetBackgroundColour(wx.Colour(255, 255, 255))  # Set panel background

class MenuBar(wx.MenuBar):
    def __init__(self, parent):
        super(MenuBar, self).__init__()
        file_menu = FileMenu(parent)
        self.Append(file_menu, "File")

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MainFrame, self).__init__(*args, **kwargs)
        #self.menu_bar = MenuBar(self)
        self.main_panel = MainPanel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        #sizer.Add(self.menu_bar, 0, wx.EXPAND)
        sizer.Add(self.main_panel, 1, wx.EXPAND)
        self.SetSizer(sizer)
        #self.SetMenuBar(self.menu_bar)

if __name__ == '__main__':
    app = wx.App()
    frame = MainFrame(parent=None, title="SimpleApp", size=(800, 600))
    frame.Show()
    app.MainLoop()

Process: Python [70663]
Path: /usr/local/Cellar/python@3.8/3.8.3_2/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python
Identifier: org.python.python
Version: 3.8.3 (3.8.3)
Code Type: X86-64 (Native)
Parent Process: bash [53304]
Responsible: Terminal [811]
User ID: 501

Date/Time: 2024-01-06 19:36:59.293 +0800
OS Version: macOS 11.7.8 (20G1351)
Report Version: 12
Anonymous UUID: 798D5949-13BC-AAAE-88AA-6C98545D50C6

Sleep/Wake UUID: D5806B84-A7B4-4970-91CA-24625F5F1A48

Time Awake Since Boot: 360000 seconds
Time Since Wake: 12000 seconds

System Integrity Protection: enabled

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [70663]

Thank you very much, this is the problem. It works well after I commenting out the line of adding self.menu_bar to sizer.