On 21/06/2012 18:07, Dave Angel wrote:
On 06/21/2012 11:19 AM, Rotwang wrote:
Hi all, I'm using Python 2.7.2 on Windows 7 and a module I've written
is acting strangely. I can reproduce the behaviour in question with
the following:

--- begin bugtest.py ---

import threading, Tkinter, os, pickle

class savethread(threading.Thread):
     def __init__(self, value):
         threading.Thread.__init__(self)
         self.value = value
     def run(self):
         print 'Saving:',
         with open(os.path.join(os.getcwd(), 'bugfile'), 'wb') as f:
             pickle.dump(self.value, f)
         print 'saved'

class myclass(object):
     def gui(self):
         root = Tkinter.Tk()
         root.grid()
         def save(event):
             savethread(self).start()
         root.bind('s', save)
         root.wait_window()

m = myclass()
m.gui()

--- end bugtest.py ---


Here's the problem: suppose I fire up Python and type

import bugtest

and then click on the Tk window that spawns and press 's'. Then
'Saving:' gets printed, and an empty file named 'bugfile' appears in
my current working directory. But nothing else happens until I close
the Tk window; as soon as I do so the file is written to and 'saved'
gets printed. If I subsequently type

bugtest.m.gui()

and then click on the resulting window and press 's', then 'Saving:
saved' gets printed and the file is written to immediately, exactly as
I would expect. Similarly if I remove the call to m.gui from the
module and just call it myself after importing then it all works fine.
But it seems as if calling the gui within the module itself somehow
stops savethread(self).run from finishing its job while the gui is
still alive.

Can anyone help?



I did not study your code, as I'm not very familiar with tkinter.
However, I think I know your problem:

You do not want to try to start up threads from within a import.  An
import is special, and somehow blocks threading while it's running.

That would explain it.


Consequently, a module should not try to do anything too fancy from
within its top-level code.  Add in the traditional:

def main():
     m = myclass()
     m.gui()

if __name__ == "__main__":
     main()

and just run it from the command line, as    python bugtest.py

In fact, running the module directly from the command line makes it work properly as-is.

Thanks for your post.

--
Hate music? Then you'll hate this:

http://tinyurl.com/psymix
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to