Hello,
The Tkinter code definitely looks buggy and since that's not our code we
decided the best option would be to replace it, so Tim has written a new
module to do just that. If anyone is having trouble with this bug then
you can put the two attached files into the directory
ccpnmr1.0/python/memops/gui. One file, QueryDialogBox.py, is the new
module. The other file, DataEntry.py, is an update of an existing module
which is the place where QueryDialogBox is called. (Fortunately the
offending tkSimpleDialog module was only used in DataEntry.)
Wayne
On Tue, 16 Aug 2005, Tim Stevens wrote:
> > d = apply(_QueryFloat, (title, prompt), kw)
> > File "/usr/lib64/python2.2/lib-tk/tkSimpleDialog.py", line 179, in
> > __init__
> > Dialog.__init__(self, parent, title)
> > File "/usr/lib64/python2.2/lib-tk/tkSimpleDialog.py", line 64, in
> > __init__
> > self.grab_set()
> > File "/usr/lib64/python2.2/lib-tk/Tkinter.py", line 493, in grab_set
> > self.tk.call('grab', 'set', self._w)
> > TclError: grab failed: window not viewable
>
>
> Looks like this is a bug in Tk. I cannot always reproduce the error, it
> seems to depend on timings/processor load etc.
>
> Although we'll look for a better solution. If you have access to your
> Tkinter installation lib-tk/Tkinter.py, after making a backup, change
> line 493 (or the equivalent in grab_set()) from:
>
> self.tk.call('grab', 'set', self._w)
>
> to:
>
> self.lift()
> self.tk.call('grab', 'set', self._w)
>
>
> Tim
>
> -------------------------------------------------------------------------------
> Dr Tim Stevens Email: [log in to unmask]
> Department of Biochemistry [log in to unmask]
> University of Cambridge Phone: +44 1223 766022 (office)
> 80 Tennis Court Road +44 7816 338275 (mobile)
> Old Addenbrooke's Site +44 1223 364613 (home)
> Cambridge CB2 1GA WWWeb: http://www.bio.cam.ac.uk/~tjs23
> United Kingdom http://www.pantonia.co.uk
> -------------------------------------------------------------------------------
> ------ +NH3CH(CH(CH3)OH)C(O)NHCH(CH(CH3)CH2CH3)C(O)NHCH(CH2CH2SCH3)CO2- -------
> -------------------------------------------------------------------------------
>
"""
======================COPYRIGHT/LICENSE START==========================
DataEntry.py: <write function here>
Copyright (C) 2005 Wayne Boucher, Rasmus Fogh, Tim Stevens and Wim Vranken (University of Cambridge and EBI/MSD)
=======================================================================
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
A copy of this license can be found in ../../../license/LGPL.license
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
======================COPYRIGHT/LICENSE END============================
for further information, please contact :
- CCPN website (http://www.ccpn.ac.uk/)
- MSD website (http://www.ebi.ac.uk/msd/)
=======================================================================
If you are using this software for academic purposes, we suggest
quoting the following references:
===========================REFERENCE START=============================
R. Fogh, J. Ionides, E. Ulrich, W. Boucher, W. Vranken, J.P. Linge, M.
Habeck, W. Rieping, T.N. Bhat, J. Westbrook, K. Henrick, G. Gilliland,
H. Berman, J. Thornton, M. Nilges, J. Markley and E. Laue (2002). The
CCPN project: An interim report on a data model for the NMR community
(Progress report). Nature Struct. Biol. 9, 416-418.
Wim F. Vranken, Wayne Boucher, Tim J. Stevens, Rasmus
H. Fogh, Anne Pajon, Miguel Llinas, Eldon L. Ulrich, John L. Markley, John
Ionides and Ernest D. Laue (2005). The CCPN Data Model for NMR Spectroscopy:
Development of a Software Pipeline. Proteins 59, 687 - 696.
===========================REFERENCE END===============================
"""
import memops.gui.QueryDialogBox as QueryDialogBox
from memops.universal.Constants import True, False
from memops.gui.FileSelectPopup import FileSelectPopup
def askString(title, prompt, initial_value = '', parent = None):
return QueryDialogBox.askString(title, prompt,initialvalue=initial_value,
parent=parent)
def askInteger(title, prompt, initial_value = '', min_value = None,
max_value = None, parent = None):
return QueryDialogBox.askInteger(title, prompt, initialvalue=initial_value,
minvalue=min_value, maxvalue=max_value, parent=parent)
def askFloat(title, prompt, initial_value = '', min_value = None,
max_value = None, parent = None):
return QueryDialogBox.askFloat(title, prompt, initialvalue=initial_value,
minvalue=min_value, maxvalue=max_value, parent=parent)
def askFile(title, prompt, initial_value = '', parent = None,
dismiss_text='Cancel', extra_dismiss_text = ''):
if (parent):
popup = FileSelectPopup(parent, title=title, prompt=prompt, show_file=True,
dismiss_text=dismiss_text,
extra_dismiss_text=extra_dismiss_text,
file=initial_value)
file = popup.getFile()
popup.destroy()
return file
else:
return askString(title, prompt, initial_value)
def askDir(title, prompt, initial_value = '', parent = None,
dismiss_text='Cancel', extra_dismiss_text = '', default_dir = None):
if (parent):
popup = FileSelectPopup(parent, title=title, prompt=prompt, show_file=False,
dismiss_text=dismiss_text,
extra_dismiss_text=extra_dismiss_text,
file=initial_value, default_dir = default_dir)
dir = popup.getDirectory()
popup.destroy()
return dir
else:
return askString(title, prompt, initial_value)
class DataEntry:
def askString(self, title, prompt, initial_value = '', parent = None, *args, **kw):
return askString(title, prompt, initial_value, parent)
def askInteger(self, title, prompt, initial_value = '', min_value = None,
max_value = None, parent = None, *args, **kw):
return askInteger(title, prompt, initial_value, min_value, max_value, parent)
def askFloat(self, title, prompt, initial_value = '', min_value = None,
max_value = None, parent = None, *args, **kw):
return askFloat(title, prompt, initial_value, min_value, max_value, parent)
def askFile(self, title, prompt, initial_value = '', parent = None,
dismiss_text='Cancel', extra_dismiss_text = '', *args, **kw):
return askFile(title, prompt, initial_value, parent)
def askDir(self, title, prompt, initial_value = '', parent = None,
dismiss_text='Cancel', extra_dismiss_text = '', default_dir = None, *args, **kw):
return askDir(title, prompt, initial_value, parent, default_dir = default_dir)
dataEntry = DataEntry()
if (__name__ == '__main__'):
import Tkinter
r = Tkinter.Tk()
print dataEntry.askString('ask string title', 'ask string prompt')
print dataEntry.askInteger('ask integer title', 'ask integer prompt')
print dataEntry.askFloat('ask float title', 'ask float prompt')
print dataEntry.askFile('ask file title', 'ask file prompt', parent=r)
print dataEntry.askDir('ask dir title', 'ask dir prompt', parent=r)
import Tkinter
from memops.gui.Label import Label
from memops.gui.Entry import Entry
from memops.gui.Frame import Frame
from memops.gui.ButtonList import ButtonList
from memops.gui.MessageReporter import showWarning
from memops.general.Implementation import ApiError
class QueryDialogBox(Tkinter.Toplevel):
def __init__(self,parent,title='Dialog Box',prompt='Prompt',
initialvalue=None, minvalue=None, maxvalue=None,
position=(50,50),returnType=type('a') ):
if parent is None:
self.parent = Tkinter._default_root
else:
self.parent = parent
Tkinter.Toplevel.__init__(self, parent)
self.response = None
self.prompt = prompt
self.initVal = initialvalue
self.minVal = minvalue
self.maxVal = maxvalue
self.returnType = returnType
self.transient(parent)
self.title(title or '')
mainFrame = Tkinter.Frame(self)
mainFrame.pack(padx=2, pady=2)
self.drawButtons('OK','Cancel')
self.entry = self.body(mainFrame)
self.lift() # so it is viewable
self.grab_set() # make modal
self.protocol('WM_WINDOW_DELETE', self.cancel)
self.bind('<Return>', self.ok)
self.bind('<Escape>', self.cancel)
if parent is not None:
dx = parent.winfo_rootx()+position[0]
dy = parent.winfo_rooty()+position[1]
self.geometry('+%d+%d' % (dx,dy))
self.wait_window(self)
def body(self, frame):
label = Label(frame, text=self.prompt)
entry = Entry(frame, text=self.initVal, bg='white')
label.grid(row=0, column=0, sticky=Tkinter.W)
entry.grid(row=1, column=0, sticky=Tkinter.W)
entry.focus_set() # for the keypresses
return entry
def cancel(self, *event):
# event may come from keypress
if self.parent:
self.parent.focus_set()
Tkinter.Toplevel.destroy(self)
def ok(self, *event):
# event may come from keypress
self.response = self.getResponse()
if self.response is not None:
self.update_idletasks()
self.destroy()
else:
self.initial_focus.focus_set()
def drawButtons(self, okText='OK', cancelText='Cancel'):
texts = [okText, cancelText]
commands = [self.ok, self.cancel]
buttonList = ButtonList(self, texts=texts, commands=commands)
buttonList.buttons[0].config(default=Tkinter.ACTIVE)
buttonList.pack()
def getResponse(self):
response = self.entry.get()
if self.returnType == type(1):
try:
response = int(response)
except:
raise ApiError('Value not an integer')
response = self.checkValue(response)
elif self.returnType == type(1.0):
try:
response = float(response)
except:
raise ApiError('Value not a floating point number')
response = self.checkValue(response)
elif self.returnType == type('a'):
response = response.strip()
else:
raise ApiError('Unknown return type for query box')
return response
def checkValue(self, value):
if (self.minVal is not None) and (value < self.minVal):
showWarning('Value is less than minimum value (%s)' % self.minVal)
value = None
elif (self.maxVal is not None) and (value > self.maxVal):
showWarning('Value is greater than maximum value (%s)' % self.maxVal)
value = None
return value
def askInteger(title, prompt, parent=None, **kw):
kw['returnType'] = type(1)
dialog = QueryDialogBox(parent, title, prompt, **kw)
return dialog.response
def askFloat(title, prompt, parent=None, **kw):
kw['returnType'] = type(1.0)
dialog = QueryDialogBox(parent, title, prompt, **kw)
return dialog.response
def askString(title, prompt, parent=None, **kw):
kw['returnType'] = type('a')
dialog = QueryDialogBox(parent, title, prompt, **kw)
return dialog.response
|