0

I'm developing an application what have its functions set in different files.

The main file have a tkinter interface and the buttons, entrys and labels are in other file, like this:

Mainfile.py

from tkinter import *

class Program:
    def __init__(self, root):
        root.geometry('200x200')
        self.main_frame = Frame(root)
        self.main_frame.pack()

        import Buttons
        self.branch = Buttons.New_Button(self.main_frame)
        
        #Here i wuold like to verify the hipotetic variable after the main_frame were destroyed
        if self.branch.hipotetic_variable:

        root.mainloop()

app = Program(Tk())

Buttons.py

from tkinter import *
import functools

class New_Button:
    def __init__(self, using_frame):
        self.button_1 = Button(using_frame, text = 'Button 1', command=functools.partial(self.Func, using_frame))
        self.button_1.pack()

    def Func(self, to_destroy):
        to_destroy.destroy()
        #Here is the hipotetic variable what i would like to verify with if statment 
        self.hipotetic_variable = True

The problem is that I want to keep managing the program in the main file calling the other functions and implementing it, but I cannot verify if it's time to update the screen because mainloop makes impossible to verify it using a while loop and an hipotetic variable that's created after user pressed button.

I wold like to know if there is an way to update an variable contained in the Buttons.py file on Mainfile.py to keep implementing all other canvas in this file.

martineau
  • 119,623
  • 25
  • 170
  • 301

1 Answers1

1

Your if self.branch.hipotetic_variable: check in the Program.__init__() method is only going to be executed when the Program class instance gets created initially, which is before the button that could change the value of the variable could have been pressed. You also don't want to make the hipotetic_variable an attribute of the Button because that will be destroyed along with the Frame it is in when that's destroyed in the button callback function.

Tkinter applications are user-event driven, meaning that they're "run" by responding to events (that's what mainloop is all about). This type of programming paradigm is different from the procedural or imperative one you're probably used to.

Therefore to do what you want requires setting things up so an event that the program can respond to will be generated, which in this case to when the frame is destroyed. One way to do that is by taking advantage of tkinter Variable classes to hold this hipotetic variable you're interested in. It looks like a boolean, so I used a tkinter BooleanVar to hold its value. One interesting thing about Variables is that you can have changes to their values "traced" by defining functions to be called whenever that happens. That's what I have done in the code below, and the callback function in this case — check_hipotetic_variable() — updates a Label to display the new value of the variable when it's called.

Below is your code with the modifications necessary to use a tkinter BooleanVar and trace changes to its value.

Mainfile.py

from tkinter import *
import Buttons

class Program:
    def __init__(self, root):
        root.geometry('200x200')
        self.main_frame = Frame(root)
        self.main_frame.pack()

        self.notice_lbl = Label(root, text='')
        self.notice_lbl.pack(side=BOTTOM)

        self.hipotetic_variable = BooleanVar(value=False)
        # Set up a trace "write" callback for whenever its contents are changed.
        self.hipotetic_variable.trace('w', self.check_hipotetic_variable)

        self.branch = Buttons.New_Button(self.main_frame, self.hipotetic_variable)

        root.mainloop()

    def check_hipotetic_variable(self, *args):
        """Display value of the hipotetic variable."""
        value = self.hipotetic_variable.get()
        self.notice_lbl.config(text=f'hipotetic variable is: {value}')


app = Program(Tk())

Buttons.py

from tkinter import *
import functools

class New_Button:
    def __init__(self, using_frame, variable):
        self.button_1 = Button(using_frame, text = 'Button 1',
                               command=functools.partial(self.Func, using_frame))
        self.button_1.pack()
        self.variable = variable  # Save for use in callback.

    def Func(self, to_destroy):
        to_destroy.destroy()
        self.variable.set(True)  # # Change value of the variable.

P.S. I noticed you're not following the PEP 8 - Style Guide for Python Code, which makes reading your code harder to read and follow that if you're were following them — for that reason I strongly suggest you read the guide and start following the suggestions, especially the Naming Conventions which apply to functions and variable names, as well as the names of script files.

martineau
  • 119,623
  • 25
  • 170
  • 301