wxPython having trouble with frame objects

Mike Driscoll kyosohma at gmail.com
Fri May 1 17:24:41 EDT 2009


On Apr 30, 11:52 pm, Dave Angel <da... at ieee.org> wrote:
> Soumen banerjee wrote:
> > Hello,
> > you say that  frame_1 is an attribute of the main class. The main
> > class here is guithread right? so any instance of guithread should
> > also have an attribute called frame_1 isnt it? Excuse me if im getting
> > this wrong, since i am somewhat new to python.
> > Regards
> > Soumen
>
> > On Fri, May 1, 2009 at 9:05 AM, CM <cmpyt... at gmail.com> wrote:
>
> >> On Apr 30, 9:54 pm, Soumen banerjee <soume... at gmail.com> wrote:
>
> >>> Hello,
> >>> I am using wxglade to design a gui which i am using in another script.
> >>> Here are the codes
>
> >>> The main file:
> >>> import wx,gui,threading
> >>> class guithread(threading.Thread):
> >>>    def run(self):
> >>>        app =x.PySimpleApp(0)
> >>>        wx.InitAllImageHandlers()
> >>>        self.frame_1 =ui.MyFrame(None, -1, "")
> >>>        app.SetTopWindow(self.frame_1)
> >>>        self.frame_1.Show()
> >>>        app.MainLoop()
> >>> gui1=ithread()
> >>> gui1.start()
> >>> class changer(threading.Thread):
> >>>    def run(self):
> >>>        gui1.frame_1.text_ctrl_1.Setvalue("hello")
> >>> chang=anger()
> >>> chang.start()
>
> >>> and The GUI file (gui.py, imported in the above)
> >>> import wx
>
> >>> # begin wxGlade: extracode
> >>> # end wxGlade
>
> >>> class MyFrame(wx.Frame):
> >>>    def __init__(self, *args, **kwds):
> >>>        # begin wxGlade: MyFrame.__init__
> >>>        kwds["style"] =x.DEFAULT_FRAME_STYLE
> >>>        wx.Frame.__init__(self, *args, **kwds)
> >>>        self.text_ctrl_1 =x.TextCtrl(self, -1, "")
> >>>        self.slider_1 =x.Slider(self, -1, 0, 0, 10)
> >>>        self.Open =x.Button(self, -1, "Open")
> >>>        self.button_4 =x.Button(self, -1, "Pause/Resume")
> >>>        self.button_5 =x.Button(self, -1, "Quit")
>
> >>>        self.__set_properties()
> >>>        self.__do_layout()
>
> >>>        self.Bind(wx.EVT_COMMAND_SCROLL, self.slider, self.slider_1)
> >>>        self.Bind(wx.EVT_BUTTON, self.open, self.Open)
> >>>        self.Bind(wx.EVT_BUTTON, self.pause, self.button_4)
> >>>        self.Bind(wx.EVT_BUTTON, self.quit, self.button_5)
> >>>        # end wxGlade
>
> >>>    def __set_properties(self):
> >>>        # begin wxGlade: MyFrame.__set_properties
> >>>        self.SetTitle("frame_1")
> >>>        self.SetSize((522, 457))
> >>>        # end wxGlade
>
> >>>    def __do_layout(self):
> >>>        # begin wxGlade: MyFrame.__do_layout
> >>>        sizer_1 =x.BoxSizer(wx.VERTICAL)
> >>>        sizer_2 =x.BoxSizer(wx.VERTICAL)
> >>>        sizer_3 =x.BoxSizer(wx.HORIZONTAL)
> >>>        sizer_2.Add(self.text_ctrl_1, 7, wx.EXPAND, 0)
> >>>        sizer_2.Add(self.slider_1, 0, wx.EXPAND, 0)
> >>>        sizer_3.Add(self.Open, 0, wx.LEFT, 70)
> >>>        sizer_3.Add((52, 20), 0, 0, 0)
> >>>        sizer_3.Add(self.button_4, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
> >>>        sizer_3.Add((55, 23), 0, 0, 0)
> >>>        sizer_3.Add(self.button_5, 0, 0, 0)
> >>>        sizer_2.Add(sizer_3, 1, wx.EXPAND, 0)
> >>>        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
> >>>        self.SetSizer(sizer_1)
> >>>        self.Layout()
> >>>        # end wxGlade
>
> >>>    def slider(self, event): # wxGlade: MyFrame.<event_handler>
> >>>        print "Event handler `slider' not implemented!"
> >>>        event.Skip()
>
> >>>    def open(self, event): # wxGlade: MyFrame.<event_handler>
> >>>        print "Event handler `open' not implemented!"
> >>>        event.Skip()
>
> >>>    def pause(self, event): # wxGlade: MyFrame.<event_handler>
> >>>        print "Event handler `pause' not implemented!"
> >>>        event.Skip()
>
> >>>    def quit(self, event): # wxGlade: MyFrame.<event_handler>
> >>>        print "Event handler `quit' not implemented!"
> >>>        event.Skip()
>
> >>> # end of class MyFrame
>
> >>> if __name__ ="__main__":
> >>>    app =x.PySimpleApp(0)
> >>>    wx.InitAllImageHandlers()
> >>>    frame_1 =yFrame(None, -1, "")
> >>>    app.SetTopWindow(frame_1)
> >>>    frame_1.Show()
> >>>    app.MainLoop()
>
> >>> The problem here is that when i run the main file, i am told that
> >>> 'guithread' object has no attribute 'frame_1' whereas i seem to have
> >>> defined
> >>> self.frame_1=i.MyFrame etc.
>
> >> Your statement above means that self--that is, the instance of
> >> your main class--has an attribute called frame_1, and that name
> >> refers to an instance of the MyFrame class from the gui module.
>
> >> It does not mean that the guithread object has an attribute named
> >> frame_1.  In order to do that, you should have written:
>
> >> guithread.frame_1 =omething
>
> >>> The idea here is to access a gui element running in a thread from a
> >>> separate thread. Please help
>
> >> I would post wxPython related questions on the wxPython mailing
> >> list, which is excellent.
> >>http://www.wxpython.org/maillist.php
>
> >> HTH,
> >> Che
> >> --
> >>http://mail.python.org/mailman/listinfo/python-list
>
> Don't top-post. It puts things entirely out of order. Now the order of
> the parts of this message are 3, 1, 2, 4
>
> Two things at least are wrong here, either of which is fatal.
>    1) you have two threads doing GUI stuff.  Can't be done, at least not in wxPython.  Certain things can be done in a second thread, but definitely not constructing Frames and such.


You are correct...but I think that's pretty common across GUI
toolkits. The GUI has it's own main loop that will get blocked if
another thread tries to do something or you'll end up with strange
behavior. As far as I know, each toolkit has its own methods for
working around this. In wxPython's case, you can use wx.CallAfter,
wx.CallLater and several others to manipulate the GUI from a thread.

There's some other ways of going about this on the wxPython wiki:
http://wiki.wxpython.org/LongRunningTasks

- Mike




More information about the Python-list mailing list