Henry S. Thompson | 4 Feb 09:50 2005
Picon
Picon

Problem with 'cascade' and state=disabled (maybe)

Python2.3, Tk 8.3, RedHat Linux.

I spent most of yesterday chasing a _very_ obscure menu problem.  Core
symptom: after some incremental menu building followed by cascaded
entry enabling/disabling, menu entry 0, although claiming
(correctly, as I built it) to be of type 'cascade', returns

  <cmdName object at 0x0829fcc8>

as the value of entrycget(0,'menu'), instead of 

  .xyzzy.foobar....

I _cannot_ find anything in my code which is doing this, I can't even
localise it very well, it seems to be asynchronous, but adding
debugging printouts in Tkinter.Misc._configure confirms that I'm not
changing the entry explicitly.

Does this ring _any_ bells with anyone?  I've installed a workaround
to cache the correct value of 'menu' and re-install it whenever it
gets trashed, but that leaves a very bad taste in my mouth.

Thanks

ht (new to this list, but long-time Python/XML/Tkinter developer)
--

-- 
 Henry S. Thompson, HCRC Language Technology Group, University of Edinburgh
                     Half-time member of W3C Team
    2 Buccleuch Place, Edinburgh EH8 9LW, SCOTLAND -- (44) 131 650-4440
            Fax: (44) 131 650-4587, e-mail: ht <at> inf.ed.ac.uk
(Continue reading)

Stewart Midwinter | 4 Feb 09:57 2005
Picon

Re: Problem with 'cascade' and state=disabled (maybe)

Henry, I did some work on enabling and disabling menus.  I even posted
some stuff on this to the list a while back, so you can search for it.

I was able to enable or disable main menu items, but never cascaded
items individually.  Are you able to address them individually?

cheers
S

--

-- 
Stewart Midwinter
stewart <at> midwinter.ca
stewart.midwinter <at> gmail.com
Henry S. Thompson | 4 Feb 10:16 2005
Picon
Picon

Re: Problem with 'cascade' and state=disabled (maybe)

Stewart Midwinter <stewart.midwinter <at> gmail.com> writes:

> Henry, I did some work on enabling and disabling menus.  I even posted
> some stuff on this to the list a while back, so you can search for it.

I indeed saw your posts, thanks.

> I was able to enable or disable main menu items, but never cascaded
> items individually.  Are you able to address them individually?

This code has been shipping for years (in XED [1]), and I've used
deeply nested cascades and enabling/disabling of individual items
without trouble up until recently.  I can't be sure, but I _think_ the
problem only arose with Python2.3.

A good starting point would simply be to find out where the cmdName
object is getting created -- I can't immediately determine even
whether it's a Tcl/Tk object or a Python/(_)Tkinter object. . .

ht

[1] http://www.ltg.ed.ac.uk/~ht/xed.html
--

-- 
 Henry S. Thompson, HCRC Language Technology Group, University of Edinburgh
                     Half-time member of W3C Team
    2 Buccleuch Place, Edinburgh EH8 9LW, SCOTLAND -- (44) 131 650-4440
            Fax: (44) 131 650-4587, e-mail: ht <at> inf.ed.ac.uk
                   URL: http://www.ltg.ed.ac.uk/~ht/
[mail really from me _always_ has this .sig -- mail without it is forged spam]
(Continue reading)

Douglas S. Blank | 5 Feb 00:43 2005
Picon

Tkinter and Threads

Hi, I'm running some Tkinter code that works fine on some machines, but 
doesn't on others. The error I get is:

   ...
   File "/usr/lib/python2.3/lib-tk/Tkinter.py", line 2066, in create_oval
     return self._create('oval', args, kw)
   File "/usr/lib/python2.3/lib-tk/Tkinter.py", line 2049, in _create
     return getint(self.tk.call(
RuntimeError: main thread is not in main loop

This code works under Fedora Core 2, Python 2.3.3 with Tkinter 1.177, 
but doesn't under Debian, Python 2.3.4, with Tkinter 1.177. I see that 
the error is raised in _tkinter.c because the Tk interpreter is in a 
different thread from where I am attempting to run this code.

The questions: is this error dependent on whether Tkinter was compiled 
with or without threads? If so, is there a way I can, via Python, find 
out the method Tkinter was compiled? Is there a workaround for this 
problem (short of rewriting my code)? Will going to Python 2.4 alter 
this behavior?

The situation is that I create a canvas in a thread, and have another 
thread running that calls a callback that updates the canvas.

Thanks for any hints!

-Doug

--

-- 
Douglas S. Blank,         Assistant Professor
(Continue reading)

Stewart Midwinter | 5 Feb 02:54 2005
Picon

Re: Tkinter and Threads

Douglas:

After reading your post I'm reminded of a scene early in Ghostbusters
I where Venkmann says "whatever you do, don't cross the rays (threads)
! That would be very, very, bad! "

Russell Owen's page of 'common Tkinter pitfalls and how to avoid
them', at the following URL:
http://www.astro.washington.edu/rowen/TkinterSummary.html, says that
"all Tkinter access must be from the main thread (or more precisely,
from the thread that calls the mainloop). Violating this is likely to
cause nasty and mysterious symptoms such as freezes and core dumps.
Yes, this makes combining multi-threading and Tkinter very difficult.
The only fully safe technique I have found it polling (e.g. use
'freeze' from the main loop to poll a threading Queue that your thread
writes).

since you have two separate threads both working on the same widgets,
the surprising thing may not be that you are having difficulties, but
rather that it worked at all!

HTH
Stewart

--

-- 
Stewart Midwinter
stewart <at> midwinter.ca
stewart.midwinter <at> gmail.com
Henry S. Thompson | 5 Feb 12:54 2005
Picon
Picon

Re: Problem with 'cascade' and state=disabled (maybe)

I should have added that this problem does _not_ occur with Python2.3
and Tcl/Tk 8.3 on Windows . . .

ht
--

-- 
 Henry S. Thompson, HCRC Language Technology Group, University of Edinburgh
                     Half-time member of W3C Team
    2 Buccleuch Place, Edinburgh EH8 9LW, SCOTLAND -- (44) 131 650-4440
            Fax: (44) 131 650-4587, e-mail: ht <at> inf.ed.ac.uk
                   URL: http://www.ltg.ed.ac.uk/~ht/
[mail really from me _always_ has this .sig -- mail without it is forged spam]
Stewart Midwinter | 5 Feb 16:59 2005
Picon

Re: Tkinter and Threads

Douglas, here's a small app showing threading to update a canvas. 
Pretty simple little app but it may be of use. I found it on a website
that Ed Blake discovered with lots of good example.

S

On Fri, 4 Feb 2005 18:54:47 -0700, Stewart Midwinter
<stewart.midwinter <at> gmail.com> wrote:
> Douglas:
> 
> After reading your post I'm reminded of a scene early in Ghostbusters
> I where Venkmann says "whatever you do, don't cross the rays (threads)
> ! That would be very, very, bad! "
> 
> Russell Owen's page of 'common Tkinter pitfalls and how to avoid
> them', at the following URL:
> http://www.astro.washington.edu/rowen/TkinterSummary.html, says that
> "all Tkinter access must be from the main thread (or more precisely,
> from the thread that calls the mainloop). Violating this is likely to
> cause nasty and mysterious symptoms such as freezes and core dumps.
> Yes, this makes combining multi-threading and Tkinter very difficult.
> The only fully safe technique I have found it polling (e.g. use
> 'freeze' from the main loop to poll a threading Queue that your thread
> writes).
> 
> since you have two separate threads both working on the same widgets,
> the surprising thing may not be that you are having difficulties, but
> rather that it worked at all!
> 
> HTH
(Continue reading)

Jeff Epler | 6 Feb 17:50 2005
Picon

Re: Problem with 'cascade' and state=disabled (maybe)

Do you have a full program that demonstrates the problem?

It's *likely* that str(w.entrycget(0, 'menu')) will return the menu's path
as a string, in all cases.

It's also possible that
    import Tkinter
    Tkinter.wantobjects = 0
before creating any interpeter will get you a string instead.

Tcl started as a typeless language:  everything is a string, but some
strings can be interpreted as lists, as numbers, or as commands.  In
later versions, Tcl gained an "object" representation, with a C type
called TclObj* which could hold just a string, an efficient
representation of numbers or lists, a pointer directly to a command,
etc.

With 'wantobjects = 1' (the default), a wrapper of a TclObject* can be
returned from Tkinter calls, rather than a string.  In this case, you're
getting the command object that corresponds to the menu widget, rather
than the string naming the menu widget, or the Python object that wraps
that particular menu widget.

Jeff
_______________________________________________
Tkinter-discuss mailing list
Tkinter-discuss <at> python.org
http://mail.python.org/mailman/listinfo/tkinter-discuss
(Continue reading)

Henry S. Thompson | 7 Feb 22:35 2005
Picon
Picon

Re: Problem with 'cascade' and state=disabled (maybe)

Jeff Epler <jepler <at> unpythonic.net> writes:

> Do you have a full program that demonstrates the problem?
>
> It's *likely* that str(w.entrycget(0, 'menu')) will return the menu's path
> as a string, in all cases.

Nope, that's precisely the bug.

> It's also possible that
>     import Tkinter
>     Tkinter.wantobjects = 0
> before creating any interpeter will get you a string instead.

Yes, that 'fixed' the problem.  But of course it had the side-effect
of causing other uses of entryget to _stop_ returning numbers and go
back to their old behaviour of returning strings.

> Tcl started as a typeless language:  everything is a string, but some
> strings can be interpreted as lists, as numbers, or as commands.  In
> later versions, Tcl gained an "object" representation, with a C type
> called TclObj* which could hold just a string, an efficient
> representation of numbers or lists, a pointer directly to a command,
> etc.
>
> With 'wantobjects = 1' (the default), a wrapper of a TclObject* can be
> returned from Tkinter calls, rather than a string.  In this case, you're
> getting the command object that corresponds to the menu widget, rather
> than the string naming the menu widget, or the Python object that wraps
> that particular menu widget.
(Continue reading)

Henry S. Thompson | 7 Feb 22:55 2005
Picon
Picon

Re: Problem with 'cascade' and state=disabled (maybe)

Yes, so following up my own message, I find

        if (value->typePtr == app->ProcBodyType) {
	  /* fall through: return tcl object. */
	}

in _tkinter:FromObj, which is what does the Tcl->Python conversion if
wantobjects=1

I understand that this is sometimes pbly the right thing, but
certainly _not_ for entrycget(n,'menu').

Or at least, if it _is_ right, then nametowidget should do the right
thing with the result. . .

ht
--

-- 
 Henry S. Thompson, HCRC Language Technology Group, University of Edinburgh
                     Half-time member of W3C Team
    2 Buccleuch Place, Edinburgh EH8 9LW, SCOTLAND -- (44) 131 650-4440
            Fax: (44) 131 650-4587, e-mail: ht <at> inf.ed.ac.uk
                   URL: http://www.ltg.ed.ac.uk/~ht/
[mail really from me _always_ has this .sig -- mail without it is forged spam]

Gmane