Matt,
 
A key PyMOL concept for Tkinter developer to grasp is that Tkinter runs in a separate thread from PyMOL.  Thus, direct calls to Tkinter from a PyMOL thread will fail erratically, as observed below. 
 
Fortunately, PyMOL is built so that it can receive API calls asychronously from any thread.  Therefore, you can develop using Tkinter from the its own thread, and then message PyMOL from there.  The only hard part is launching your GUI, which is something you cannot do from a PyMOL script or program directly.  Instead, you add a new item in the Plugin menu or a whole new menu for your GUI as part of your initialization.
 
The plugin approach is the safe way to add new functionality using Tkinter.  See modules/pmg_tk/startup/__init__.py for example code to get you started.  
 
Cheers,
Warren
 
--
DeLano Scientific LLC
Subscriber Support Services
mailto:delsci@delsci.info
 


From: pymol-users-bounces@lists.sourceforge.net [mailto:pymol-users-bounces@lists.sourceforge.net] On Behalf Of Matthew O'Meara
Sent: Friday, April 25, 2008 12:46 PM
To: PyMOL-users@lists.sourceforge.net
Subject: [PyMOL] access to tkinter root for new Toplevel?

Hi All,

I would like to write a Wizard that spawns a separate window.  Right now I'm just calling Tkinter.Toplevel() with no arguments but it dies with non-deterministic tkinter errors.  I think the issue is I need to pass the Tkinter.Tk() instance into the Toplevel command. 

1) Is there a way I can get access to the main Tkinter.Tk() instance from within my Wizard?


I've made a simple version of what I would like that shows the behavior I'm seeing.  To run, copy this into a file called testWizard.py and place into the wizard directory.  Since I installed from Distutils on linux, my wizard directory is /usr/local/lib/python2.5/site-packages/pymol/wizard/.  Then fire up pymol and type into the command line 'wizard testWizard'.  If you version is <1.0 try deleting '_self=cmd' and '_self'.   For me it crashes about every third or so time, usually with different errors.


from pymol.wizard import Wizard
from pymol import cmd
import pymol
import Tkinter


class TestWizard(Wizard):

    def __init__(self,_self=cmd):
        Wizard.__init__(self, _self)

        self.res_table = Tkinter.Tk()  # <- pass app.root in here????

        for i in range( 1000 ): Tkinter.Button(self.res_table, text=str(i)).pack()


Thanks in advance!
Matt