wxPython having trouble with frame objects

  • Thread starter Soumen banerjee
  • Start date
S

Soumen banerjee

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 = wx.PySimpleApp(0)
       wx.InitAllImageHandlers()
       self.frame_1 = gui.MyFrame(None, -1, "")
       app.SetTopWindow(self.frame_1)
       self.frame_1.Show()
       app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
   def run(self):
       gui1.frame_1.text_ctrl_1.Setvalue("hello")
chang=changer()
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"] = wx.DEFAULT_FRAME_STYLE
       wx.Frame.__init__(self, *args, **kwds)
       self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
       self.slider_1 = wx.Slider(self, -1, 0, 0, 10)
       self.Open = wx.Button(self, -1, "Open")
       self.button_4 = wx.Button(self, -1, "Pause/Resume")
       self.button_5 = wx.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 = wx.BoxSizer(wx.VERTICAL)
       sizer_2 = wx.BoxSizer(wx.VERTICAL)
       sizer_3 = wx.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 = wx.PySimpleApp(0)
   wx.InitAllImageHandlers()
   frame_1 = MyFrame(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=gui.MyFrame etc.

The idea here is to access a gui element running in a thread from a
separate thread. Please help
regards
Soumen
 
C

CM

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 = wx.PySimpleApp(0)
       wx.InitAllImageHandlers()
       self.frame_1 = gui.MyFrame(None, -1, "")
       app.SetTopWindow(self.frame_1)
       self.frame_1.Show()
       app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
   def run(self):
       gui1.frame_1.text_ctrl_1.Setvalue("hello")
chang=changer()
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"] = wx.DEFAULT_FRAME_STYLE
       wx.Frame.__init__(self, *args, **kwds)
       self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
       self.slider_1 = wx.Slider(self, -1, 0, 0, 10)
       self.Open = wx.Button(self, -1, "Open")
       self.button_4 = wx.Button(self, -1, "Pause/Resume")
       self.button_5 = wx.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 = wx.BoxSizer(wx.VERTICAL)
       sizer_2 = wx.BoxSizer(wx.VERTICAL)
       sizer_3 = wx.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 = wx.PySimpleApp(0)
   wx.InitAllImageHandlers()
   frame_1 = MyFrame(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=gui.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 = something
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
 
S

Soumen banerjee

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

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 = wx.PySimpleApp(0)
       wx.InitAllImageHandlers()
       self.frame_1 = gui.MyFrame(None, -1, "")
       app.SetTopWindow(self.frame_1)
       self.frame_1.Show()
       app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
   def run(self):
       gui1.frame_1.text_ctrl_1.Setvalue("hello")
chang=changer()
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"] = wx.DEFAULT_FRAME_STYLE
       wx.Frame.__init__(self, *args, **kwds)
       self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
       self.slider_1 = wx.Slider(self, -1, 0, 0, 10)
       self.Open = wx.Button(self, -1, "Open")
       self.button_4 = wx.Button(self, -1, "Pause/Resume")
       self.button_5 = wx.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 = wx.BoxSizer(wx.VERTICAL)
       sizer_2 = wx.BoxSizer(wx.VERTICAL)
       sizer_3 = wx.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 = wx.PySimpleApp(0)
   wx.InitAllImageHandlers()
   frame_1 = MyFrame(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=gui.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 = something
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
 
S

Soumen banerjee

Hello,
Another thing, here i tried changing self.frame_1 to
guithread.frame_1, so that that part of the code now reads:-

import wx,gui,threading
class guithread(threading.Thread):
def run(self):
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
guithread.frame_1 = gui.MyFrame(None, -1, "")
app.SetTopWindow(guithread.frame_1)
guithread.frame_1.Show()
app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
def run(self):
gui1.frame_1.text_ctrl_1.Setvalue("hello")
chang=changer()
chang.start()

I still get guithread object has no attribute frame_1. I must be doing
something wrong

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

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 = wx.PySimpleApp(0)
       wx.InitAllImageHandlers()
       self.frame_1 = gui.MyFrame(None, -1, "")
       app.SetTopWindow(self.frame_1)
       self.frame_1.Show()
       app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
   def run(self):
       gui1.frame_1.text_ctrl_1.Setvalue("hello")
chang=changer()
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"] = wx.DEFAULT_FRAME_STYLE
       wx.Frame.__init__(self, *args, **kwds)
       self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
       self.slider_1 = wx.Slider(self, -1, 0, 0, 10)
       self.Open = wx.Button(self, -1, "Open")
       self.button_4 = wx.Button(self, -1, "Pause/Resume")
       self.button_5 = wx.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 = wx.BoxSizer(wx.VERTICAL)
       sizer_2 = wx.BoxSizer(wx.VERTICAL)
       sizer_3 = wx.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 = wx.PySimpleApp(0)
   wx.InitAllImageHandlers()
   frame_1 = MyFrame(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=gui.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 = something
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
 
D

Dave Angel

Soumen said:
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

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
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.
2) you have no synchronization between the two threads you start, so the changer thread may very well get to its usage of frame_1 long before guithread assigns it. This is probably the cause of your current symptom. Now, you could perhaps "fix" it by assigning it something in the guithread constructor (you don't define one), but although that'd get you further, problem #1 is fatal.
 
S

Soumen banerjee

Hello,
Im not adding any GUI elements from the changer thread. Im just
attempting to change the value of a preexisting widget made in thread
one. The point is that i need to display text generated in thread 2 in
a GUI generated in thread 1.
As far as inter thread synchronization is concerned, i see your point.
So i took this approach

import wx,gui,threading
fix=0
i=1
class guithread(threading.Thread):
def run(self):
global fix
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
guithread.frame_1 = gui.MyFrame(None, -1, "")
app.SetTopWindow(guithread.frame_1)
guithread.frame_1.Show()
print "setting fix"
fix=1
app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
def run(self):
print fix
gui1.frame_1.text_ctrl_1.SetValue("hello")
print fix
while i:
if fix == 1:
print "starting changer"
chang=changer()
chang.start()
i=0
This works, but is there anything simpler?
Regards
Soumen
 
D

Dave Angel

Soumen said:
Hello,
The code works almost perfectly. I was able to correct some small
things, and get it to work brilliantly. I would like to thank you for
your dedicated help. My understanding of the matter here has improved
by a lot due to your kind help. I will further work on your
suggestions. By the way why should the general rule in 5 apply with
respect to private and global variables?
Regards
Soumen


<snip>
You accidentally top-posted, so your response is at the beginning,
rather than in sequence. You also forgot to CC the PythonList, so nobody
else will see it.

One typo I thought of after hitting "send" was I omitted the 'self'
parameter when calling the parent __init__() methods.

function variables are preferred over globals for several reasons. One
is that there's less likelihood of accidentally getting the wrong
value. If two different functions use the same name for something,
there's no confusion unless one of them decides to make it global. This
is referred to as namespace pollution. Generally, the fewer names that
are visible at any moment, the better. Much better to get an error than
use the worng one. Other namespace cases is my preference of simple
import over from xxx import yyy. It means that a reference to
something from the import takes more typing, but is clearer to the reader.

Second problem with globals is that if you write a successful program to
do something once, it very well might not work if you just repeat it,
because you might forget to re-initialize the globals. If this were the
only problem, I might solve it by making a "init_globals()" function
that uses the global keyword to export the names it's initializing.
Then make sure you run init_globals() before running main().
Unfortunately, there are more problems, so forget this "solution."

Third problem with globals is involved in refactoring. When you first
write a glob of code, you tend to put lots in one module. Then when you
better understand it, you refactor it into separate modules. If it was
coded with globals, this refactoring is much more painful.

Fourth problem with globals is in multithreading. Any reference to
mutable shared information has to be considered carefully, and each
global is a potential hazard.

So, are there uses for globals? Certainly. First use, simple utility
programs that fit in one file, run non-interactively, and for whom
development pretty much stops when they "work." Second, any immutable
variable, whether or not it's literally protected. There are many of
these already in the system. For example, all your function names are
global variables. Third, the system already defines some, such as in
the sys module. Some of these are constant, such as the path
separator. Others are changeable, but not usually while the application
is running, like sys.path.

If you have to define new ones, either put them in a separate module (as
sys does), or put them in a single class, as instance attributes. Then,
when refactoring, at least you only have one thing that's got to
beshared between modules. Any any code that refers to them will be
using the same name for them.
 
M

Mike Driscoll

Hello,
Im not adding any GUI elements from the changer thread. Im just
attempting to change the value of a preexisting widget made in thread
one. The point is that i need to display text generated in thread 2 in
a GUI generated in thread 1.
As far as inter thread synchronization is concerned, i see your point.
So i took this approach

import wx,gui,threading
fix=0
i=1
class guithread(threading.Thread):
    def run(self):
        global fix
        app = wx.PySimpleApp(0)
        wx.InitAllImageHandlers()
        guithread.frame_1 = gui.MyFrame(None, -1, "")
        app.SetTopWindow(guithread.frame_1)
        guithread.frame_1.Show()
        print "setting fix"
        fix=1
        app.MainLoop()
gui1=guithread()
gui1.start()
class changer(threading.Thread):
    def run(self):
        print fix
        gui1.frame_1.text_ctrl_1.SetValue("hello")
print fix
while i:
    if fix == 1:
        print "starting changer"
        chang=changer()
        chang.start()
        i=0
This works, but is there anything simpler?
Regards
Soumen

For additional ideas on using threads in wxPython, see the wiki:

http://wiki.wxpython.org/LongRunningTasks

- Mike
 
M

Mike Driscoll

Soumen said:
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
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

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top