Hi Chris, > -----Original Message----- > From: Chris Rebert [mailto:c...@rebertia.com] > Sent: Sunday, February 22, 2009 11:48 > To: Barak, Ron > Cc: python-list@python.org; wxpython-us...@lists.wxwidgets.org > Subject: Re: "metaclass conflict" error: where is noconflict ? > > On Sun, Feb 22, 2009 at 1:37 AM, Barak, Ron <ron.ba...@lsi.com> wrote: > > Hi Chris, > > > >> -----Original Message----- > >> From: ch...@rebertia.com [ > > mailto:ch...@rebertia.com] On > >> Behalf Of Chris Rebert > >> Sent: Thursday, February 19, 2009 22:58 > >> To: Barak, Ron > >> Cc: python-list@python.org; wxpython-us...@lists.wxwidgets.org > >> Subject: Re: "metaclass conflict" error: where is noconflict ? > >> > >> On Thu, Feb 19, 2009 at 5:01 AM, Barak, Ron > <ron.ba...@lsi.com> wrote: > >> > Hi, > >> > > >> > I have a class derived from two parents (in blue below), > >> which gives > >> > me the following error: > >> > > >> > $ python -u ./failover_pickle_demo09.py Traceback (most > recent call > >> > last): > >> > File "./failover_pickle_demo09.py", line 291, in <module> > >> > class ListControl(wx.Frame, CopyAndPaste): > >> > TypeError: Error when calling the metaclass bases > >> > metaclass conflict: the metaclass of a derived class > must be a > >> > (non-strict) subclass of the metaclasses of all its > bases Googling > >> > suggested I should add from noconflict import classmaker and > >> > > >> > __metaclass__=classmaker() > >> > to this class. > >> > > >> > However, I don't seem able to find where to get the > >> noconflict module from. > >> > > >> > Do any of you where noconflict could be > downloaded/installed from ? > >> > >> From what I could google, you should in theory be able to fix the > >> problem (without using any 3rd party module) by doing: > >> > >> class ListControlMeta(type(wx.Frame), type(CopyAndPaste)): > >> pass > >> > >> class ListControl(wx.Frame, CopyAndPaste): > >> __metaclass__ = ListControlMeta > >> #rest of class... > >> > >> Cheers, > >> Chris > > > > Applying your suggestion: > > > > class ListControlMeta(type(wx.Frame), type(CopyAndPaste)): > > pass > > > > class ListControl(wx.Frame, CopyAndPaste): > > def __init__(self, parent, id, title, list, max_list_width, > > log_stream, > > style=wx.DEFAULT_FRAME_STYLE): > > > > __metaclass__= ListControlMeta > > > > > > wx.Frame.__init__(self,parent,id,title,size=(max_list_width,-1), > > style=style) > > self.list = list > > self.log_stream = log_stream > > self.list_ctrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT | > > wx.LC_NO_HEADER) > > self.list_ctrl.InsertColumn(0, title) > > for i,line_ in enumerate(list): > > self.list_ctrl.InsertStringItem(i, line_) > > ... > > > > I get: > > > > $ python -u ./failover_pickle_demo09.py Traceback (most recent call > > last): > > File "./failover_pickle_demo09.py", line 319, in <module> > > class ListControlMeta(type(wx.Frame), type(CopyAndPaste)): > > TypeError: Error when calling the metaclass bases > > multiple bases have instance lay-out conflict > > >From what I recall, that basically means that type(wx.Frame) and > type(CopyAndPaste) are both C classes that are are mutually > incompatible. It's basically the same reason you can't > subclass from both `list` and `dict` or two other built-in > types (you get the exact same error). > > Sounds like the only way to workaround this would be to do > some coding in C or to use composition rather than > inheritance for one of ListControl's superclasses.
The wx.Frame may be coded in C, but the CopyAndPaste class, which I wrote, is not (see it's listing below). Could you have a look at the CopyAndPaste class, and see if something in its construction strikes you as susspicious ? Thanks, Ron. $ cat ./CopyAndPaste.py #!/usr/bin/env python import wx class CopyAndPaste(): def __init__(self): pass def set_copy_and_paste(self): """ Setting clipboard copy-and-pasting (only copying from the application to the clipboard is supported). The "menu" menu is hidded, and is only there to facilitate the acceleration table. Both CTRL-C and CTRL-Ins are supported. """ #print line()+". set_copy_and_paste started" #print line()+". self.__dict__:",self.__dict__ menu = wx.Menu() copy_ = menu.Append(-1, "&Copy\tCtrl-Ins") # Copy with accelerator minimize_ = menu.Append(-1, "Minimize") # close_ = menu.Append(-1, "Close window\tCtrl-W") # Close window exit_ = menu.Append(-1, "E&xit application\tCtrl-X") # Close window """ #copy2_ = menu.Append(-1, "&Copy\tCtrl-C") # Copy with accelerator paste_ = menu.Append(-1, "&Paste\tShift-Ins") # Paste with accelerator paste2_ = menu.Append(-1, "&Paste\tCtrl-V") # Paste with accelerator """ self.Bind(wx.EVT_MENU, self.on_copy, copy_) self.Bind(wx.EVT_MENU, self.on_minimize, minimize_) self.Bind(wx.EVT_MENU, self.on_close, close_) self.Bind(wx.EVT_MENU, self.on_exit, exit_) #self.Bind(wx.EVT_MENU, self.on_paste, paste_) menuBar = wx.MenuBar() self.SetMenuBar(menuBar) acceltbl = wx.AcceleratorTable( [ (wx.ACCEL_CTRL, ord('C'), copy_.GetId()), (wx.ACCEL_CTRL, ord('W'), close_.GetId()), (wx.ACCEL_CTRL, ord('X'), exit_.GetId()), (wx.ACCEL_CTRL, ord('Q'), exit_.GetId()), (wx.ACCEL_CTRL, wx.WXK_INSERT, copy_.GetId()), (wx.ACCEL_CTRL, wx.WXK_NUMPAD_INSERT, copy_.GetId()), #(wx.ACCEL_CTRL, ord('V'), paste_.GetId()), #(wx.ACCEL_SHIFT, wx.WXK_INSERT, paste_.GetId()), ]) self.SetAcceleratorTable(acceltbl) # Setting popup menu self.popupmenu = menu self.Bind(wx.EVT_CONTEXT_MENU, self.on_show_popup) """ def on_paste(self, evt): wx.MessageBox("You selected 'paste'") """ def on_show_popup(self, evt): pos = evt.GetPosition() pos = self.list_ctrl.ScreenToClient(pos) self.PopupMenu(self.popupmenu, pos) def get_data_for_clipboard(self,format="text"): """ Return data ready to be copied to the clipboard. This is an abstract method - concrete subclasses must override this. Sample implementation of get_data_for_clipboard() is: def get_data_for_clipboard(self,format="text"): first_selected = self.list_ctrl.GetFirstSelected() selected_item_count = self.list_ctrl.GetSelectedItemCount() text_for_clipboard = "" for i in range(first_selected,first_selected+selected_item_count): text_for_clipboard = "%s%s\n" % (text_for_clipboard, self.list_ctrl.GetItemText(i)) return(text_for_clipboard) """ raise NotImplementedError def on_copy(self, evt): """ """ text_for_clipboard = self.get_data_for_clipboard() data = wx.TextDataObject() data.SetText(text_for_clipboard) if wx.TheClipboard.Open(): wx.TheClipboard.SetData(data) wx.TheClipboard.Close() else: wx.MessageBox("Unable to copy to the clipboard", "Error") def on_minimize(self, evt): self.Iconize() #self.parent.Iconize() def on_close(self, evt): self.Close() #self.parent.Close() def on_exit(self, evt): try: self.Parent.Close() except AttributeError: self.Close() if __name__ == "__main__": app = wx.App(redirect=False) copy_and_paste = CopyAndPaste() app.MainLoop() > > Cheers, > Chris > > -- > Follow the path of the Iguana... > http://rebertia.com > > -- http://mail.python.org/mailman/listinfo/python-list