Mailing List Archive

Tkinter bug in Misc.tkraise, Canvas.tkraise
I found a bug in using Tkinter to raise a canvas widget above later
packed (etc.) widgets. It seems Tkinter gets confused between the
Misc.tkraise() method and the Canvas.tkraise(item) methods.
The following script shows the problem:

from Tkinter import *

def raiseCanvas():
canvas1.lift()
#canvas1.tkraise()
#canvas1.widgetlift()

root = Tk()
canvas1 = Canvas(root, bg='blue')
canvas1.place(x=10, y=10, anchor=NW)
canvas2 = Canvas(root, bg='red')
canvas2.place(x=20, y=20, anchor=NW)
raiseButton = Button(root, text='raiseCanvas', command=raiseCanvas)
raiseButton.pack()
root.geometry("%dx%d" % (100,100))
root.mainloop()

which gives the following error:

Exception in Tkinter callback
Traceback (innermost last):
File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 764, in
__call__
return apply(self.func, args)
File "C:\PROGRA~1\PYTHON\RAISEC~1.PY", line 4, in raiseCanvas
canvas1.lift()
File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 1287, in
tkraise
self.tk.call((self._w, 'raise') + args)
TclError: wrong # args: should be ".8249616 raise tagOrId ?aboveThis?"

I made Tkinter do what I want by adding a method to the Misc
class and not the Canvas class:

class Misc...
def tkraise(self, aboveThis=None):
self.tk.call('raise', self._w, aboveThis)
lift = widgetlift = tkraise

so that widgetlift will call the tkraise in Misc and not the tkraise in
Canvas.

I discovered the error in developing a multiple document interface for
Tkinter
which can be found on: http://www2.zyvex.com/OpenChem/index.htm
Dockable toolbars and a tree widget can also be found there.
They probably don't look very good on unix yet.

John
Tkinter bug in Misc.tkraise, Canvas.tkraise [ In reply to ]
The following got posted in a reply tree by mistake:

I found a bug in using Tkinter to raise a canvas widget above later
packed (etc.) widgets. It seems Tkinter gets confused between the
Misc.tkraise() method and the Canvas.tkraise(item) methods.
The following script shows the problem:

from Tkinter import *

def raiseCanvas():
canvas1.lift()
#canvas1.tkraise()
#canvas1.widgetlift()

root = Tk()
canvas1 = Canvas(root, bg='blue')
canvas1.place(x=10, y=10, anchor=NW)
canvas2 = Canvas(root, bg='red')
canvas2.place(x=20, y=20, anchor=NW)
raiseButton = Button(root, text='raiseCanvas', command=raiseCanvas)
raiseButton.pack()
root.geometry("%dx%d" % (100,100))
root.mainloop()

which gives the following error:

Exception in Tkinter callback
Traceback (innermost last):
File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 764, in
__call__
return apply(self.func, args)
File "C:\PROGRA~1\PYTHON\RAISEC~1.PY", line 4, in raiseCanvas
canvas1.lift()
File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 1287, in
tkraise
self.tk.call((self._w, 'raise') + args)
TclError: wrong # args: should be ".8249616 raise tagOrId ?aboveThis?"

I made Tkinter do what I want by adding a method to the Misc
class and not the Canvas class:

class Misc...
def tkraise(self, aboveThis=None):
self.tk.call('raise', self._w, aboveThis)
lift = widgetlift = tkraise

so that widgetlift will call the tkraise in Misc and not the tkraise in
Canvas.

I discovered the error in developing a multiple document interface for
Tkinter
which can be found on: http://www2.zyvex.com/OpenChem/index.htm
Dockable toolbars and a tree widget can also be found there.
They probably don't look very good on unix yet.

John
Tkinter bug in Misc.tkraise, Canvas.tkraise [ In reply to ]
John Michelsen <john.michelsen@gte.net> wrote:
: The following got posted in a reply tree by mistake:

: I found a bug in using Tkinter to raise a canvas widget above later
: packed (etc.) widgets. It seems Tkinter gets confused between the
: Misc.tkraise() method and the Canvas.tkraise(item) methods.
: The following script shows the problem:

: from Tkinter import *

: def raiseCanvas():
: canvas1.lift()
: #canvas1.tkraise()
: #canvas1.widgetlift()

: root = Tk()
: canvas1 = Canvas(root, bg='blue')
: canvas1.place(x=10, y=10, anchor=NW)
: canvas2 = Canvas(root, bg='red')
: canvas2.place(x=20, y=20, anchor=NW)
: raiseButton = Button(root, text='raiseCanvas', command=raiseCanvas)
: raiseButton.pack()
: root.geometry("%dx%d" % (100,100))
: root.mainloop()

: which gives the following error:

: Exception in Tkinter callback
: Traceback (innermost last):
: File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 764, in
: __call__
: return apply(self.func, args)
: File "C:\PROGRA~1\PYTHON\RAISEC~1.PY", line 4, in raiseCanvas
: canvas1.lift()
: File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 1287, in
: tkraise
: self.tk.call((self._w, 'raise') + args)
: TclError: wrong # args: should be ".8249616 raise tagOrId ?aboveThis?"

: I made Tkinter do what I want by adding a method to the Misc
: class and not the Canvas class:

: class Misc...
: def tkraise(self, aboveThis=None):
: self.tk.call('raise', self._w, aboveThis)
: lift = widgetlift = tkraise

: so that widgetlift will call the tkraise in Misc and not the tkraise in
: Canvas.

: I discovered the error in developing a multiple document interface for
: Tkinter
: which can be found on: http://www2.zyvex.com/OpenChem/index.htm
: Dockable toolbars and a tree widget can also be found there.
: They probably don't look very good on unix yet.

It is not a bug with either code, it is a naming problem. The
Canvas.tkraise is calling the correct code, but it should be called
tag_raise, not tkraise (see the Text widget for naming choice).

Fredrik or Guido, is this something you can change for before 1.5.2 is
released? (I don't see anything on www.python.org/1.5/ that says when
1.5.2 will be done except "mid March", which has gone by.)

Until then, I would suggest the following fix:

from Tkinter import Canvas
Canvas.tag_raise = Canvas.tkraise
del Canvas.tkraise, Canvas.lift

This should correct the problem.

-Arcege
Tkinter bug in Misc.tkraise, Canvas.tkraise [ In reply to ]
"John Michelsen" <john.michelsen@gte.net> writes:
|
| I found a bug in using Tkinter to raise a canvas widget above later
| packed (etc.) widgets. It seems Tkinter gets confused between the
| Misc.tkraise() method and the Canvas.tkraise(item) methods.
| The following script shows the problem:
|
| from Tkinter import *
|
| def raiseCanvas():
| canvas1.lift()
| #canvas1.tkraise()
| #canvas1.widgetlift()
|
| root = Tk()
| canvas1 = Canvas(root, bg='blue')
| canvas1.place(x=10, y=10, anchor=NW)
| canvas2 = Canvas(root, bg='red')
| canvas2.place(x=20, y=20, anchor=NW)
| raiseButton = Button(root, text='raiseCanvas', command=raiseCanvas)
| raiseButton.pack()
| root.geometry("%dx%d" % (100,100))
| root.mainloop()

You can call Misc.lift (overriden by Canvas.lift) as follows:

def raiseCanvas():
Misc.lift(canvas1)

In general, you can call a base class method overriden by a subclass
method by BaseClassName.methodname(SubClassInstance, arguments).

You'll find that the same technique is used in the __init__ methods of
the Tkinter widget classes.

--
KAJIYAMA, Tamito <kajiyama@grad.sccs.chukyo-u.ac.jp>
Tkinter bug in Misc.tkraise, Canvas.tkraise [ In reply to ]
> It is not a bug with either code, it is a naming problem. The
> Canvas.tkraise is calling the correct code, but it should be called
> tag_raise, not tkraise (see the Text widget for naming choice).
>
> Fredrik or Guido, is this something you can change for before 1.5.2 is
> released? (I don't see anything on www.python.org/1.5/ that says when
> 1.5.2 will be done except "mid March", which has gone by.)

You are right that there is a naming conflict. Unfortunately the
default rules for naming Tk subcommands yield this conflict and I
didn't catch it when I (or whoever it was) originally created the
Canvas class. The Canvas.bind() method shows a precedent for naming
it tag_raise() as you propose.

Unfortunately, I cannot make this change without breaking all existing
code that was using Canvas.tkraise() for raising Canvas items (instead
of raising the Canvas itself). I can add tag_raise() and then in 1.6
we can delete the tkraise() and lift() names.

Other issues:

- As someone else suggested, the proper solution is
Misc.tkraise(canvasobject).

- /Fredrik Lundh is responsible for *documenting* Tkinter, but not for
its maintenance (although he contributed a bunch of support modules).
The maintenance of Tkinter is strictly my responsibility. (Not that I
asked for it. :-)

- 1.5.2 will more likely be released around mid-April.

--Guido van Rossum (home page: http://www.python.org/~guido/)
Tkinter bug in Misc.tkraise, Canvas.tkraise [ In reply to ]
>Until then, I would suggest the following fix:
>
> from Tkinter import Canvas
> Canvas.tag_raise = Canvas.tkraise
> del Canvas.tkraise, Canvas.lift
>
>This should correct the problem.


Yep, that works too. Thanks.

John
Tkinter bug in Misc.tkraise, Canvas.tkraise [ In reply to ]
Guido van Rossum <guido@CNRI.Reston.VA.US> wrote:
:> It is not a bug with either code, it is a naming problem. The
:> Canvas.tkraise is calling the correct code, but it should be called
:> tag_raise, not tkraise (see the Text widget for naming choice).
:>
:> Fredrik or Guido, is this something you can change for before 1.5.2 is
:> released? (I don't see anything on www.python.org/1.5/ that says when
:> 1.5.2 will be done except "mid March", which has gone by.)

: You are right that there is a naming conflict. Unfortunately the
: default rules for naming Tk subcommands yield this conflict and I
: didn't catch it when I (or whoever it was) originally created the
: Canvas class. The Canvas.bind() method shows a precedent for naming
: it tag_raise() as you propose.

Actually, I got the name "tag_raise" from the method in the Text class
of the same name.

: Unfortunately, I cannot make this change without breaking all existing
: code that was using Canvas.tkraise() for raising Canvas items (instead
: of raising the Canvas itself). I can add tag_raise() and then in 1.6
: we can delete the tkraise() and lift() names.

Good enough for me.

: Other issues:

: - As someone else suggested, the proper solution is
: Misc.tkraise(canvasobject).

The proper interim solution only, I think.

: - /Fredrik Lundh is responsible for *documenting* Tkinter, but not for
: its maintenance (although he contributed a bunch of support modules).
: The maintenance of Tkinter is strictly my responsibility. (Not that I
: asked for it. :-)

Well.. I knew he was in there somewhere. ;) Sorry, Fredrik!

: - 1.5.2 will more likely be released around mid-April.

I'm awaitin'. :)

: --Guido van Rossum (home page: http://www.python.org/~guido/)

Thanks, Guido!

-Arcege