Issue 1447222: tkinter Dialog fails when more than four buttons are used (original) (raw)
Example code:
#! /usr/bin/env python import Dialog from Tkinter import * root = Tk() Button(root, text="Hello!").pack() root.update() dialog = Dialog.Dialog(None, {'title': 'Test Dialog', 'text': "Text...", 'bitmap': '', 'default': 0, 'strings': ('Button0','Button1','Button2','Button3','Button4')}) print 'dialog: ', dialog.num
This example works well, except when clicking in Button4 that fails: Traceback (most recent call last): File "test.py", line 12, in ? dialog = Dialog.Dialog(None, {'title': 'Test Dialog', File "/usr/lib/python2.3/lib-tk/Dialog.py", line 21, in init cnf['bitmap'], cnf['default'], TypeError: getint() argument 1 must be string, not tuple
I tried to trace the error (learning in the way a little bit of python and tcl/tk ;)), mostly due to the bizarre nature of this problem (note that in tcl/tk there are no problems when creating dialogs with 4 or more buttons).
In /usr/lib/python2.3/lib-tk/Dialog/py the exception is raised because it expects a string as the result to the call to 'tk_dialog', and for some 'obscure' reason (and I mean it, I even inspected the Tcl/Tk sources looking for a reason for this) if the call to 'tk_dialog' has more than 4 buttons (more than 4 string arguments at the end) it return a tuple with only one element, the string result.
The impression I got after browsing the sources of python/tkinter and Tcl/Tk is that this may be caused because in tcl there is almost no difference between a list and string, in this way in the tcl language a string or a list containing only one string are not really different.
I have this problem when using python2.3 or python2.4 with Tcl/Tk8.4 (in my particular case under Debian/Testing distribution);
A quick workaround (although I 'm not sure if it would cause some problems with other things) would be to change 'workarounds = 1' to 'workarounds = 0' in Tkinter.py. Another option would be to change all calls to tk functions within tkinter that allways expect as a result a string...
Hernan (my apologies for making the report so long)
I just tried it here and it still happens, it also happens for the 11th button and that is it (5th and 11th). I tried it with tk 8.4 and tk 8.5, python-trunk, python 2.5.2.
I'm investigating this.
For some reason a pixel object is being returned inside a tuple. _tkinter detects a ListType object, then creates a tuple with one object, which is a pixel object and it has the value you would expect, 4 or 10.
The workaround is actually setting wantobjects to 0, which I doubt everyone will like. I've talked with a tcl developer and some interesting points were raised from the talk:
- Looking at typePtr in _tkinter isn't actually good (this is used to convert the tcl object to a proper python object), because it may not work always, like in this case. But the person also mentioned he didnt't know of any good solutions to that problem.
- Cause of the problem -- most likely: something else in the code that creates the message box is using the literal string "5" as a -borderwidth or a -padding or as something else that's passed to a widget. And the compiler uses the same Tcl_Obj * for that "5" and the "5" that you pass to [tk_dialog].
Apparently trying to fix this in Python would case some (major?) changes in _tkinter.
Interesting.. I tried testing Dialog for that bug, but generating keypress (you can combine with keyrelease too) doesn't trigger the problem (very weird to me). I will be simulating mouse clicks to see if, for some reason, the bug gets noticed.
Attaching the test I tried just in case.