Peter Billam wrote: >> Peter Billam wrote: >> window = MainWindow(application) >> if (len(sys.argv) > 1) and os.path.exists(sys.argv[1]): >> window.loadFile(sys.argv[1]) >> application.mainloop() >> File "./midimix", line 465, in loadFile >> space0.grid(row=grid_row, >> pady=round(0.5*(ymid[track_num]-ymid[track_num-1]))-50) >> ... >> _tkinter.TclError: bad pad value "-50": must be positive screen distance >> presumably because the window doesn't have dimensions before mainloop >> is entered. Can I force the window to be laid out before entering >> mainloop? Or can I invoke loadFile() after mainloop has started ? > > On 2009-03-14, Peter Otten <__pete...@web.de> wrote: >> The latter. Try >> application.after_idle(window.loadFile, sys.argv[1]) > > Thank you! That almost worked :-) It opened a window (which it didn't > do last time), and it laid out the frames and so on apparently OK, > and even posted a "Loaded v.mid" message on the StatusBar, but then > just drew a couple of zero-thickness lines right at the top of the > canvas, and failed with the same message: > File "./midimix", line 465, in loadFile > space0.grid(row=grid_row, > pady=round(0.5*(ymid[track_num]-ymid[track_num-1]))-50) > File "/usr/local/lib/python3.0/tkinter/__init__.py", > line 1845, in grid_configure > + self._options(cnf, kw)) > _tkinter.TclError: bad pad value "-50": must be positive screen distance > > but I say "almost" because I googled after_idle, and the very similar: > application.after(500, window.loadFile, sys.argv[1]) > does work, exactly as intended :-) except of course that it's a > race condition, and will fail for very impatient people or on very > slow machines. On my machine it still works with 20ms, but fails > with 10ms. Is there one extra magic trick I need to know?
I had the same kind of problems with the latest tcl/tk version (8.5): apparently, the interface goes idle before all widgets are completely displayed, and tricks like these - that used to work with former tcl/tk version - now fail... You may have a better chance with a binding on the '<<Configure>>' virtual event, which will trigger when your widget changes its size. You just have to make sure it'll trigger only once, even if the user resizes the window while your script is running... The binding should be set on the widget you query to get its dimensions. > I also tried invoking after_idle on the canvas widget: > window.canvas.after_idle(window.loadFile, sys.argv[1]) > but that fails with the same message. > (I am using python 3.0.1 in case that's, er, relevant.) On tcl/tk level, 'after idle' is actually a command that doesn't act on a widget, so calling after_idle on any widget will have exactly the same behaviour. On a more general level, if you want to have the same script that can be called either from a GUI or from the command line, you might want to separate your "functional" code from the GUI aspects, meaning have a module or a set of modules containing the part that actually does something, and doesn't know anything about from where it is called, and another module or set of modules for the GUI and/or the CLI, which display things nicely and call the first part when it has to actually do something. This would avoid problems like the one you have. > Thanks for your help, Regards, Peter HTH - Eric - -- http://mail.python.org/mailman/listinfo/python-list