FredMaster
FredMaster

Reputation: 1459

tkinter use imported function

I have the following basic app using tkinter, which has two buttons. With the first button I can open the folder including the files I want to run an analysis on and the second button then runs the analysis.

from tkinter import filedialog
from tkinter import *
from pathlib import Path
from run_analysis import create_tmp_file


class MyApp():
    def __init__(self,master):
        frame = Frame(master) 
        frame.pack()
        self.button_filedialog = Button(frame, text="Öffnen", fg="red",command=self.open_filedialog)
        self.button_analyse = Button(frame, text="Starte Analyse", fg="green", command=self.make_analysis)

        ## Unpack buttons
        self.button_filedialog.pack()
        self.button_analyse.pack()

    def open_filedialog(self):
        start_path = Path.cwd()
        self.data_path =  filedialog.askdirectory(initialdir=start_path)

    def make_analysis(self):
        create_tmp_file(self.data_path,1,0.12)

root = Tk()
app = MyApp(root)
root.mainloop()

The code runs fine. However, it is actually not what I want.

I want to call my imported function create_tmp_file directly in the second button. However, if I do replace the line

self.button_analyse = Button(frame, text="Starte Analyse", fg="green", command=self.make_analysis)

with

self.button_analyse = Button(frame, text="Starte Analyse", fg="green", command=create_tmp_file(self.data_path,1,0.12))

The code doesn't work and I receive the following error message:

AttributeError: 'MyApp' object has no attribute 'data_path'

What am I doing wrong?

Thanks!

Upvotes: 0

Views: 133

Answers (1)

Pythonista
Pythonista

Reputation: 11615

What's happening here is pretty straightforward. You're setting an attribute on the class - in this case the data_path attribute... - inside the method. But, that only happens when the method is actually invoked.

Setting the command is just a reference to it, so until it's actually called that attribute doesn't exist.

This is clearly problematic when you're giving a reference to a method - which sets the attribute but hasn't been called - then immediately invoking the method which assumes it's existence.

Upvotes: 1

Related Questions