Python Forum
[Tkinter] Return a value to __main__
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Return a value to __main__
#1
Using this example, is there a way to return the updated value or how to use the after method in the main?

import tkinter as tk

class Window(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.count = 0
        self.label = tk.Label(self, text='Hello World')
        self.label.pack()


    def counter(self):
        self.count += 1
        # self.after(1000, self.counter)
        self.label['text'] = self.count
        return self.count


if __name__ == '__main__':
    app = Window()
    app.after(1000, app.counter)
    app.mainloop()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#2
Hello,
I'm not sure I understood your request. Do you want to do this? :
import tkinter as tk


class Window(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.count = tk.IntVar()
        self.count.set(0)
        self.label = tk.Label(self, text='Hello World')
        self.label.pack()
 
 
    def counter(self):
        self.count.set(self.count.get()+1)
        self.label['text'] = self.count.get()
        self.after(1000, self.counter)

if __name__ == '__main__':
    
    app = Window()
    def trace(*event):
        print("app.couter in main", app.count.get())
    
    app.count.trace_add("write", trace)
    app.after(1000, app.counter)
    app.mainloop()
I speak Python but I don't speak English (I just read it a little). If I express myself badly, please blame the translator^^.
Reply
#3
I forgot about trace. I'm trying to learn to keep the logic separate from the presentation.
Guess what I'm trying to do is figure out how to update a field, label, etc. with out doing it in a class window.
I'm not sure if that makes sense but, it's along those lines.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#4
This is a better practice.
import tkinter as tk


class Window(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.count = 1
        self.label = tk.Label(self, text='Hello World')
        self.label.pack()
        self.counter()
 
    def counter(self):
        self.label['text'] = self.count
        self.count += 1
        self.after(1000, self.counter)

if __name__ == '__main__':

    root = tk.Tk()
    bt = tk.Button(root, text="Press to stop", command=quit)
    bt.grid()
    app = Window()
    app.grid()

    root.mainloop()
I speak Python but I don't speak English (I just read it a little). If I express myself badly, please blame the translator^^.
Reply
#5
Perhaps it would be better to put the presentation in main but, I would still have to add the logic.
Example of logic say the counter reaches 10 reset counter to 0.

I thought after would work in main as it is in the mainloop. I'll keep experimenting and searching. Thanks for the advice.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#6
This does not work:
if __name__ == '__main__':
     
    app = Window()
    def trace(*event):
        print("app.couter in main", app.count.get())
     
    app.count.trace_add("write", trace)
    app.after(1000, app.counter)
    app.mainloop()
If there was any way to interact with the window you would see that it ignores mouse and keyboard events. You need to periodically call update, and that is usually done by calling mainloop().

It is easy to tie events in your window to external logic. When reading about GUI programming you see this separation of responsibility. MVC, MVP, MVVM. In all of these you have something that represents data and state, something that displays data and state, and some kind of glue layer that ties the two together.

In this example I am just going to steal an after() event from the GUI and use it to periodically update my logic and presentation. This is not a great example. My entire model consists of time.time(). But hopefully it demonstrates the idea.
import time
import tkinter as tk

class Glue():
    def __init__(self, label):
        self.label = label
        self.start_time = time.time()
        self.label.after(1000, self.update)

    def update(self):
        self.label['text'] = str(time.time() - self.start_time)
        self.label.after(1000, self.update)

class MainWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.count = 1
        self.label = tk.Label(self, text='Hello World')
        self.label.pack()
        tk.Button(self, text="Press to stop", command=quit).pack()
 
if __name__ == '__main__':
    app = MainWindow()
    Glue(app.label)  # <- The glue that ties model and presentation
    app.mainloop()
I timed my update to a timer in this example, but you can use any event.
Reply
#7
So in essence use two classes. One to work the logic and one for presentation. Then tie the two together.
I don't know why but, for some reason I thought I could update information from the __main__. Every search shows the update in the class it self. Anyway thanks all for the input.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#8
Thee parts, not classes. There might be lots of classes or no classes, but the division of labor is three parts. I will use the Model View Controller paradigm

You have a Model part. In my line of work my Model is a piece of machinery that my application controls. In Microsoft Word the model is a document. Model is the most important part. In my example, time.time() was the model. Not a very interesting model because I cannot change the state of the clock. For my professional work the Model is about 70% of the code.

The View is the presentation of the information. This is your GUI

The controller accepts input from the user and serves as the glue between the Model and View. In my example the controller was partially implemented in tkinter and partially in the Glue class. The controller part is usually messy when compared to the Model and View. As it is the thing that binds them together, the controller has information about the model and the view. Much work in user interface design is focused on making the controller less messy.

For simple programs it is often easiest to put MVC all in one class. This doesn't hold up well as the model and view grow in complexity.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020