Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #54235 > unrolled thread

Weird ttk behaviour

Started byRotwang <sg552@hotmail.co.uk>
First post2013-09-16 17:28 +0100
Last post2013-09-18 02:20 +1000
Articles 10 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Weird ttk behaviour Rotwang <sg552@hotmail.co.uk> - 2013-09-16 17:28 +0100
    Re: Weird ttk behaviour Serhiy Storchaka <storchaka@gmail.com> - 2013-09-16 21:43 +0300
      Re: Weird ttk behaviour Rotwang <sg552@hotmail.co.uk> - 2013-09-17 12:15 +0100
    Re: Weird ttk behaviour Chris Angelico <rosuav@gmail.com> - 2013-09-17 08:34 +1000
      Re: Weird ttk behaviour Rotwang <sg552@hotmail.co.uk> - 2013-09-17 12:27 +0100
        Re: Weird ttk behaviour Chris Angelico <rosuav@gmail.com> - 2013-09-17 21:32 +1000
          Re: Weird ttk behaviour Rotwang <sg552@hotmail.co.uk> - 2013-09-17 15:25 +0100
            Re: Weird ttk behaviour Chris Angelico <rosuav@gmail.com> - 2013-09-18 00:35 +1000
              Re: Weird ttk behaviour Rotwang <sg552@hotmail.co.uk> - 2013-09-17 17:11 +0100
                Re: Weird ttk behaviour Chris Angelico <rosuav@gmail.com> - 2013-09-18 02:20 +1000

#54235 — Weird ttk behaviour

FromRotwang <sg552@hotmail.co.uk>
Date2013-09-16 17:28 +0100
SubjectWeird ttk behaviour
Message-ID<l17bj9$1qs$1@dont-email.me>
Hi all,

I've just started trying to learn how to use ttk, and I've discovered 
something that I don't understand. I'm using Python 3.3.0 in Linux Mint 
15. Suppose I create the following module:

# begin tkderp.py

import tkinter as tk
import tkinter.messagebox as _
from tkinter import ttk
from imp import reload


_root = tk.Tk()
_root.withdraw()

def f():
	style = ttk.Style(_root)
	style.theme_create('newtheme', parent = 'default')
	tk.messagebox.showwarning('test', 'test')
	style.theme_use('newtheme')
	tk.messagebox.showwarning('test', 'test')

# end tkderp.py


The function f() is supposed to spawn two warning dialogs. AIUI, the 
"style.theme.use('newtheme')" line shouldn't make any difference - it 
would refresh any existing ttk widgets and alter the appearance of any 
subsequently created ones if I had changed any of the new theme's 
settings, but in the above context nothing it does should be discernible 
to the user. If I try to call f() the first warning gets shown, but the 
second one causes an exception:

Python 3.3.1 (default, Apr 17 2013, 22:30:32)
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
 >>> import tkderp
 >>> tkderp.f()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "/home/phil/Python/tkderp.py", line 17, in f
     tk.messagebox.showwarning('test', 'test')
   File "/usr/lib/python3.3/tkinter/messagebox.py", line 87, in showwarning
     return _show(title, message, WARNING, OK, **options)
   File "/usr/lib/python3.3/tkinter/messagebox.py", line 72, in _show
     res = Message(**options).show()
   File "/usr/lib/python3.3/tkinter/commondialog.py", line 48, in show
     s = w.tk.call(self.command, *w._options(self.options))
_tkinter.TclError: unknown color name ""


If I try reloading the module and calling the function again, this time 
the first of the two warnings raises the exception. Since I don't really 
understand how the ttk.Style class works, I can't say whether this 
behaviour is expected or not. But here's what's weird. Suppose that I 
comment out the last two lines in the definition of f(), like so:

# begin modified tkderp.py

import tkinter as tk
import tkinter.messagebox as _
from tkinter import ttk
from imp import reload


_root = tk.Tk()
_root.withdraw()

def f():
	style = ttk.Style(_root)
	style.theme_create('newtheme', parent = 'default')
	tk.messagebox.showwarning('test', 'test')
	#style.theme_use('newtheme')
	#tk.messagebox.showwarning('test', 'test')

# end modified tkderp.py


Unsurprisingly, importing the module and calling f() displays a single 
warning dialog and raises no exception. If I then uncomment those two 
lines, reload the module and call f() again (by entering 
tkderp.reload(tkderp).f()), the function works like it was supposed to 
in the first place: two warnings, no exceptions. I can reload the module 
as many times as I like and f() will continue to work without any problems.

On Windows 7 (sys.version is '3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 
10:57:17) [MSC v.1600 64 bit (AMD64)]') there's no problem; f() works 
fine in the first place. Does anybody know what's going on?

[toc] | [next] | [standalone]


#54240

FromSerhiy Storchaka <storchaka@gmail.com>
Date2013-09-16 21:43 +0300
Message-ID<mailman.35.1379357008.18130.python-list@python.org>
In reply to#54235
16.09.13 19:28, Rotwang написав(ла):
> On Windows 7 (sys.version is '3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012,
> 10:57:17) [MSC v.1600 64 bit (AMD64)]') there's no problem; f() works
> fine in the first place. Does anybody know what's going on?

What _root.wantobjects() returns?

[toc] | [prev] | [next] | [standalone]


#54278

FromRotwang <sg552@hotmail.co.uk>
Date2013-09-17 12:15 +0100
Message-ID<l19dk8$ct2$1@dont-email.me>
In reply to#54240
On 16/09/2013 19:43, Serhiy Storchaka wrote:
> 16.09.13 19:28, Rotwang написав(ла):
>> On Windows 7 (sys.version is '3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012,
>> 10:57:17) [MSC v.1600 64 bit (AMD64)]') there's no problem; f() works
>> fine in the first place. Does anybody know what's going on?
>
> What _root.wantobjects() returns?

It returns True, both before and after the call to 
style.theme_use('newtheme'). Why do you ask? I've no idea what 
Tk.wantobjects is supposed to do (I tried help() and some web searches 
with no luck).

[toc] | [prev] | [next] | [standalone]


#54250

FromChris Angelico <rosuav@gmail.com>
Date2013-09-17 08:34 +1000
Message-ID<mailman.39.1379370869.18130.python-list@python.org>
In reply to#54235
On Tue, Sep 17, 2013 at 2:28 AM, Rotwang <sg552@hotmail.co.uk> wrote:
> If I then uncomment those two lines, reload the module and call f() again
> (by entering tkderp.reload(tkderp).f()), the function works like it was
> supposed to in the first place: two warnings, no exceptions. I can reload
> the module as many times as I like and f() will continue to work without any
> problems.

Reloading modules in Python is a bit messy. Are you able to tinker
with it and make it work in some way without reloading? It'd be easier
to figure out what's going on that way.

ChrisA

[toc] | [prev] | [next] | [standalone]


#54280

FromRotwang <sg552@hotmail.co.uk>
Date2013-09-17 12:27 +0100
Message-ID<l19ebk$g94$1@dont-email.me>
In reply to#54250
On 16/09/2013 23:34, Chris Angelico wrote:
> On Tue, Sep 17, 2013 at 2:28 AM, Rotwang <sg552@hotmail.co.uk> wrote:
>> If I then uncomment those two lines, reload the module and call f() again
>> (by entering tkderp.reload(tkderp).f()), the function works like it was
>> supposed to in the first place: two warnings, no exceptions. I can reload
>> the module as many times as I like and f() will continue to work without any
>> problems.
>
> Reloading modules in Python is a bit messy. Are you able to tinker
> with it and make it work in some way without reloading? It'd be easier
> to figure out what's going on that way.

I can't think what else I could try, do you have any suggestions? The 
problem first appeared in a much larger module (I was trying to replace 
some tkinter widgets that looked bad on Linux with their ttk 
equivalents); the only reason I noticed the thing about reloading is 
that I was trying to reproduce the error in a short module by repeatedly 
making changes and reloading.

[toc] | [prev] | [next] | [standalone]


#54281

FromChris Angelico <rosuav@gmail.com>
Date2013-09-17 21:32 +1000
Message-ID<mailman.59.1379417584.18130.python-list@python.org>
In reply to#54280
On Tue, Sep 17, 2013 at 9:27 PM, Rotwang <sg552@hotmail.co.uk> wrote:
> On 16/09/2013 23:34, Chris Angelico wrote:
>>
>> On Tue, Sep 17, 2013 at 2:28 AM, Rotwang <sg552@hotmail.co.uk> wrote:
>>>
>>> If I then uncomment those two lines, reload the module and call f() again
>>> (by entering tkderp.reload(tkderp).f()), the function works like it was
>>> supposed to in the first place: two warnings, no exceptions. I can reload
>>> the module as many times as I like and f() will continue to work without
>>> any
>>> problems.
>>
>>
>> Reloading modules in Python is a bit messy. Are you able to tinker
>> with it and make it work in some way without reloading? It'd be easier
>> to figure out what's going on that way.
>
>
> I can't think what else I could try, do you have any suggestions? The
> problem first appeared in a much larger module (I was trying to replace some
> tkinter widgets that looked bad on Linux with their ttk equivalents); the
> only reason I noticed the thing about reloading is that I was trying to
> reproduce the error in a short module by repeatedly making changes and
> reloading.

If reloading and doing it again makes things different, what happens
if you simply trigger your code twice without reloading?

I've no idea if it'll help, it just seems like an attack vector on the
problem, so to speak.

ChrisA

[toc] | [prev] | [next] | [standalone]


#54303

FromRotwang <sg552@hotmail.co.uk>
Date2013-09-17 15:25 +0100
Message-ID<l19op8$dse$1@dont-email.me>
In reply to#54281
On 17/09/2013 12:32, Chris Angelico wrote:
> [...]
>
> If reloading and doing it again makes things different, what happens
> if you simply trigger your code twice without reloading?
>
> I've no idea if it'll help, it just seems like an attack vector on the
> problem, so to speak.

Thanks for the suggestion, here's what I've found with some more 
testing. If I rewrite the function f() like this:

def f(fail):
     style = ttk.Style(_root)
     style.theme_create('newtheme', parent = 'default')
     tk.messagebox.showwarning('test', 'test')
     if fail:
         style.theme_use('newtheme')
         tk.messagebox.showwarning('test', 'test')


then I import the module and call f(False) followed by f(True), the 
second call raises an exception just like the original function. I've 
tried variations of the above, such as defining a module-level global 
style instead of having one created during the function call, and the 
end result is always the same. However, suppose instead I define two 
modules, tkderp and tkderp2; both have a function f as defined in my OP, 
but the first has the last two lines of f commented out, and the second 
doesn't (i.e. tkderp is the modified tkderp from before, and tkderp2 is 
the original). Then I do this:

 >>> import tkderp
 >>> tkderp.f()
 >>> import tkderp2
 >>> tkderp2.f()


In that case the second call to f() works fine - two warnings, no 
exception. In fact, if I replace tkderp with this:

# begin tkderp.py

import tkinter as tk

_root = tk.Tk()
_root.withdraw()

# end tkderp.py


then simply importing tkderp before tkderp2 is enough to make the latter 
work properly - this

 >>> import tkderp2
 >>> tkderp2.f()


raises an exception, but this

 >>> import tkderp
 >>> import tkderp2
 >>> tkderp2.f()


doesn't. Any ideas what may be going on?

[toc] | [prev] | [next] | [standalone]


#54305

FromChris Angelico <rosuav@gmail.com>
Date2013-09-18 00:35 +1000
Message-ID<mailman.75.1379428566.18130.python-list@python.org>
In reply to#54303
On Wed, Sep 18, 2013 at 12:25 AM, Rotwang <sg552@hotmail.co.uk> wrote:
> In fact, if I replace tkderp with this:
>
>
> # begin tkderp.py
>
> import tkinter as tk
>
> _root = tk.Tk()
> _root.withdraw()
>
> # end tkderp.py
>
>
> then simply importing tkderp before tkderp2 is enough to make the latter
> work properly

Nice piece of detective work! Alas, I don't know tkinter well enough
to help with the details, but this is exactly what I'd like to hear if
I were trying to pick this up and debug it :)

Tkinter experts, anywhere? Where's Ranting Rick when you need him...

ChrisA

[toc] | [prev] | [next] | [standalone]


#54318

FromRotwang <sg552@hotmail.co.uk>
Date2013-09-17 17:11 +0100
Message-ID<l19uvh$mqu$1@dont-email.me>
In reply to#54305
On 17/09/2013 15:35, Chris Angelico wrote:
> On Wed, Sep 18, 2013 at 12:25 AM, Rotwang <sg552@hotmail.co.uk> wrote:
>> In fact, if I replace tkderp with this:
>>
>>
>> # begin tkderp.py
>>
>> import tkinter as tk
>>
>> _root = tk.Tk()
>> _root.withdraw()
>>
>> # end tkderp.py
>>
>>
>> then simply importing tkderp before tkderp2 is enough to make the latter
>> work properly
>
> Nice piece of detective work! Alas, I don't know tkinter well enough
> to help with the details, but this is exactly what I'd like to hear if
> I were trying to pick this up and debug it :)

I don't know tkinter well enough either, but the fact that it behaves 
differently on Linux and Windows suggests to me that at least one 
version is bugging out. Do you think this is worth raising on 
bugs.python.org?


> Tkinter experts, anywhere? Where's Ranting Rick when you need him...

Last time I saw him was in this thread:

https://mail.python.org/pipermail/python-list/2013-June/650257.html

[toc] | [prev] | [next] | [standalone]


#54320

FromChris Angelico <rosuav@gmail.com>
Date2013-09-18 02:20 +1000
Message-ID<mailman.84.1379434859.18130.python-list@python.org>
In reply to#54318
On Wed, Sep 18, 2013 at 2:11 AM, Rotwang <sg552@hotmail.co.uk> wrote:
> I don't know tkinter well enough either, but the fact that it behaves
> differently on Linux and Windows suggests to me that at least one version is
> bugging out. Do you think this is worth raising on bugs.python.org?

Possibly, but I'd keep it here on python-list for the moment; it may
be you're actually using undefined behaviour somewhere, in which case
the solution is to change your code. Once someone else (someone who
actually knows what he's talking about, for preference) can confirm
what's going on, it'll be bug report time, I think.

ChrisA

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web