I am trying to import MainMenuBar class from filemenu.py to my main class and instantiate it in my main class init method in wxPython but I am getting error
RuntimeError: super-class __init__() of type MainMenuBar was never called
Here is my main class
import os
import wx
from wx.lib.agw.scrolledthumbnail import ScrolledThumbnail, Thumb, PILImageHandler
import filemenu
class MainFrameImageThumbnail(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Mockup", size=(1200,800))
self.scroll = ScrolledThumbnail(self, 10, size=(200,1200))
self.panel = wx.Panel(self)
self.scroll.SetBackgroundColour((5,5,5))
font = wx.Font( wx.FontInfo(10).Bold())
self.scroll.SetCaptionFont(font)
self.scroll.SetThumbOutline(4)
self.scroll.SetDropShadow(False)
self.scroll.SetSelectionColour(wx.Colour(120,80,255))
sizer = wx.BoxSizer(wx.VERTICAL)
self.menuCreation()
def menuCreation(self):
mainMenu = filemenu.MainMenuBar()
app = wx.App(False)
frame = MainFrameImageThumbnail()
frame.Show(True)
app.MainLoop()
Here is my filemenu.py
import os
import wx
APP_EXIT = 1
class MainMenuBar(wx.Panel):
def __init__(self):
self.FileTab()
def OnQuit(self, e):
self.Close()
def FileTab(self):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
qmi = wx.MenuItem(fileMenu, APP_EXIT, '&Quit\tCtrl Q')
qmi.SetBitmap(wx.Bitmap('power-on.png'))
fileMenu.Append(qmi)
self.Bind(wx.EVT_MENU, self.OnQuit, id=APP_EXIT)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
Am I calling it wrong? Is there a specific way to do this in WxPython?
EDIT:
Following an example, I attempted this which looks more correct but I am getting another error
My main class:
import os
import wx
from wx.lib.agw.scrolledthumbnail import ScrolledThumbnail, Thumb, PILImageHandler
import filemenu
class MainFrameImageThumbnail(wx.Frame):
def __init__(self):
super().__init__(parent=None,title="Mockup", size=(1200,800))
self.scroll = ScrolledThumbnail(self, 10, size=(200,1200))
self.panel = wx.Panel(self)
self.scroll.SetBackgroundColour((5,5,5))
font = wx.Font( wx.FontInfo(10).Bold())
self.scroll.SetCaptionFont(font)
self.scroll.SetThumbOutline(4)
self.scroll.SetDropShadow(False)
self.scroll.SetSelectionColour(wx.Colour(120,80,255))
sizer = wx.BoxSizer(wx.VERTICAL)
self.menu = filemenu.MainMenuBar(self)
self.menu.FileTab()
app = wx.App(False)
frame = MainFrameImageThumbnail()
frame.Show(True)
app.MainLoop()
my filemenu.py
import os
import wx
APP_EXIT = 1
class MainMenuBar(wx.Panel):
def __init__(self,parent):
super().__init__(parent)
def OnQuit(self, e):
self.Close()
def FileTab(self):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
qmi = wx.MenuItem(fileMenu, APP_EXIT, '&Quit\tCtrl Q')
qmi.SetBitmap(wx.Bitmap('power-on.png'))
fileMenu.Append(qmi)
self.Bind(wx.EVT_MENU, self.OnQuit, id=APP_EXIT)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
Now I get this error:
AttributeError: 'MainMenuBar' object has no attribute 'SetMenuBar'
CodePudding user response:
There is a lot going on in the filemenu.py
, using a wx.Panel
here in conjunction with a menu makes no sense. See what to change to make it work.
New filemenu.py
import os
import wx
APP_EXIT = 1
# using a wxPanel complicates stuff and is not necessary
# class MainMenuBar(wx.Panel):
class MainMenuBar:
def __init__(self,parent):
# we do no need to initialize parent class because there is none
#super().__init__(parent)
# instead we keep track of the parent frame we want
# to integrate the menu bar into
self.parent = parent
def OnQuit(self, e):
# adapt to who is parent
self.parent.Close()
def FileTab(self):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
qmi = wx.MenuItem(fileMenu, APP_EXIT, '&Quit\tCtrl Q')
qmi.SetBitmap(wx.Bitmap('power-on.png'))
fileMenu.Append(qmi)
# who is parent -> wx.Frame
self.parent.Bind(wx.EVT_MENU, self.OnQuit, id=APP_EXIT)
menubar.Append(fileMenu, '&File')
# who is parent -> wx.Frame
self.parent.SetMenuBar(menubar)
CodePudding user response:
Your menubar is defined as a sub-classed wx.Panel
, so it doesn't have a SetMenuBar
function. A wx.Frame
has that, which means you must assign it in the main frame.
In the menu code you define the Bind for closure, that that isn't going to do anything, essentially you're trying to close the menubar and you want to close the frame. The binding of the event must also occur in relation to the parent not the menubar.
Many, code the menubar and menus in the main parent, as this makes life much easier but I realise that these days everyone wants a separate class for everything. This can come back to bite you.
Here's your amended code. It isn't the only way to code this but it's one way.
main:
import os
import wx
from wx.lib.agw.scrolledthumbnail import ScrolledThumbnail, Thumb, PILImageHandler
import filemenu
class MainFrameImageThumbnail(wx.Frame):
def __init__(self):
super().__init__(parent=None,title="Mockup", size=(1200,800))
self.scroll = ScrolledThumbnail(self, 10, size=(200,1200))
self.panel = wx.Panel(self)
self.scroll.SetBackgroundColour((5,5,5))
font = wx.Font( wx.FontInfo(10).Bold())
self.scroll.SetCaptionFont(font)
self.scroll.SetThumbOutline(4)
self.scroll.SetDropShadow(False)
self.scroll.SetSelectionColour(wx.Colour(120,80,255))
sizer = wx.BoxSizer(wx.VERTICAL)
self.menu = filemenu.MainMenuBar()
bar = self.menu.FileTab()
self.SetMenuBar(bar)
self.Bind(wx.EVT_MENU, self.OnQuit, id=self.menu.qmi.GetId())
def OnQuit(self, event):
self.Destroy()
app = wx.App(False)
frame = MainFrameImageThumbnail()
frame.Show(True)
app.MainLoop()
menu:
import os
import wx
APP_EXIT = 1
class MainMenuBar(wx.MenuBar):
def __init__(self):
super().__init__()
def OnQuit(self, e):
self.Close()
def FileTab(self):
self.menubar = wx.MenuBar()
fileMenu = wx.Menu()
self.qmi = wx.MenuItem(fileMenu, APP_EXIT, '&Quit\tCtrl Q')
#qmi.SetBitmap(wx.Bitmap('power-on.png'))
fileMenu.Append(self.qmi)
self.menubar.Append(fileMenu, '&File')
return self.menubar