Tkinter help - Why this behavior ? (py3)

D

Dodo

Hi,

let's consider this exemple :

from tkinter import *
from tkinter.ttk import *

class First:
def __init__(self):
self.root = Tk()
B = Button(self.root, command=self.op)
B.pack()

self.root.mainloop()

def op(self):
Second(self)
print("print")


class Second:
def __init__(self, parent):
root = Toplevel(parent.root)
root.grab_set()

root.mainloop()


First()



when I close the second window, the print is NOT executed. It's done
when I close the first window.
Why do it "freeze" my function?

Dorian
 
A

Alf P. Steinbach

* Dodo, on 05.06.2010 15:46:
Hi,

let's consider this exemple :

from tkinter import *
from tkinter.ttk import *

class First:
def __init__(self):
self.root = Tk()
B = Button(self.root, command=self.op)
B.pack()

self.root.mainloop()

def op(self):
Second(self)
print("print")


class Second:
def __init__(self, parent):
root = Toplevel(parent.root)
root.grab_set()

root.mainloop()


First()



when I close the second window, the print is NOT executed. It's done
when I close the first window.
Why do it "freeze" my function?

First, sorry about Thunderbird 3.x messing up the quoting of the code.

Don't know what they did to introduce all those bugs, but anyway, Thunderbird
3.x is an example that even seasoned programmers introduce an unbelievable
number of bugs, I think mostly just by repeating code patterns blindly.

In your code above you're doing as the TB programmers presumably did, repeating
a code pattern that you've seen has worked, without fully grokking it. The call
to 'mainloop' enters a loop. A button press causes your callback to be invoked
from within that loop, but your code then enters a new 'mainloop'.

Don't.

Except for modal dialogs the single top level 'mainloop' suffices (all it does
is to dispatch "messages" to "handlers", such as your button press callback).
So, just place a single call to 'mainloop' at the end of your program. Remove
the calls in 'First' and 'Second'.


Cheers & hth.,

- Alf
 
D

Dodo

Le 05/06/2010 19:07, Alf P. Steinbach a écrit :
* Dodo, on 05.06.2010 15:46:

First, sorry about Thunderbird 3.x messing up the quoting of the code.

Don't know what they did to introduce all those bugs, but anyway,
Thunderbird 3.x is an example that even seasoned programmers introduce
an unbelievable number of bugs, I think mostly just by repeating code
patterns blindly.

In your code above you're doing as the TB programmers presumably did,
repeating a code pattern that you've seen has worked, without fully
grokking it. The call to 'mainloop' enters a loop. A button press causes
your callback to be invoked from within that loop, but your code then
enters a new 'mainloop'.

Don't.

Except for modal dialogs the single top level 'mainloop' suffices (all
it does is to dispatch "messages" to "handlers", such as your button
press callback). So, just place a single call to 'mainloop' at the end
of your program. Remove the calls in 'First' and 'Second'.


Cheers & hth.,

- Alf

How do I create custom modal dialogs then?

Dorian
 
R

rantingrick

Hi,

let's consider this exemple :

from tkinter import *
from tkinter.ttk import *

class First:
        def __init__(self):
                self.root = Tk()
                B = Button(self.root, command=self.op)
                B.pack()

                self.root.mainloop()

        def op(self):
                Second(self)
                print("print")

class Second:
        def __init__(self, parent):
                root = Toplevel(parent.root)
                root.grab_set()

                root.mainloop()


Please don't write code like this, it is very, very, very, very ugly.
Python is an OOP language do use that to your advantage and you will
make your life much easier! Here is a better alternative.


import Tkinter as tk
from Tkconstants import *
import tkSimpleDialog

class MyDialog(tkSimpleDialog.Dialog):
def body(self, master):
prompt = "Hello from my custom dialog!\nAlthough with
something this simple i should have used tkMessageBox."
tk.Label(self, text=prompt).pack()

def validate(self):
print 'I need to put some code here, maybe'
return True

def apply(self):
print 'I need to put some code here, maybe'


class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
b=tk.Button(self, text='Show Dialog', command=self.showDialog)
b.pack(padx=5, pady=5)

def showDialog(self):
d = MyDialog(self)

if __name__ == '__main__':
app = App()
app.mainloop()
 
D

Dodo

Le 09/06/2010 18:49, rantingrick a écrit :
Please don't write code like this, it is very, very, very, very ugly.
Python is an OOP language do use that to your advantage and you will
make your life much easier! Here is a better alternative.


import Tkinter as tk
from Tkconstants import *
import tkSimpleDialog

class MyDialog(tkSimpleDialog.Dialog):
def body(self, master):
prompt = "Hello from my custom dialog!\nAlthough with
something this simple i should have used tkMessageBox."
tk.Label(self, text=prompt).pack()

def validate(self):
print 'I need to put some code here, maybe'
return True

def apply(self):
print 'I need to put some code here, maybe'


class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
b=tk.Button(self, text='Show Dialog', command=self.showDialog)
b.pack(padx=5, pady=5)

def showDialog(self):
d = MyDialog(self)

if __name__ == '__main__':
app = App()
app.mainloop()

Could you please explain to me what's the big difference?

Dorian
 
D

Dodo

Le 09/06/2010 19:13, Dodo a écrit :
Le 09/06/2010 18:49, rantingrick a écrit :

Could you please explain to me what's the big difference?

Dorian

I think I see it now. Seems good to be
 
T

Terry Reedy

Could you please explain to me what's the big difference?

What Rick wrote is pretty standard and similar to the example in Lib Ref
24.1.2.2. A Simple Hello World Program and others you can find. It get
the right things done in the right place, and just once.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top