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:

  1. 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.
  2. 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.