Home > OS >  Python - How can I associate a function to a button?
Python - How can I associate a function to a button?

Time:07-13

I wrote this function to let the user inter the file and when he clicked on the bottom it will require a csv file and i want to let the user choose the directory where he can save that ? but i can't do that can any one help me please . this is the main file that i call it all the function of the two other scripte

CodePudding user response:

You have file_path = TK.StringVar() that tries to create a variable (a string variable), but it can't as it doesn't have a root/parent. You have also copy-pasted the functions and some other lines twice; they're not needed, so I've removed the extras:

import tkinter as TK
from tkinter import ttk
from tkinter import filedialog
from tkinter.messagebox import askquestion
from tkinter.filedialog import asksaveasfile

#from DiagSpecification import *
#from DextRteParser import *


def browseFiles(tk_event=None, *args, **kw):
    # browse file path
    _fpath = filedialog.askopenfilename(initialdir="/", title="Open your document",
                                        filetypes=[('arxml files', '.arxml'), ('all files', '.*')])
    
    file_path.set(_fpath)


def get_path():
    print(file_path.get())
    return file_path.get()


def save():
    files = [('All Files', '*.*'),
             ('Python Files', '*.py'),
             ('Text Document', '*.txt')]
    file = asksaveasfile(filetypes=files, defaultextension=files)


def exit():
    answer = askquestion(title='Quit?', message='Really quit?')
    if answer == 'yes':
        root.destroy()


#  create an Interface
root = TK.Tk()
root.title("File explorer")

file_path = TK.StringVar()


labelframe = ttk.LabelFrame(root, text="Selecting files", padding="5px", )

# Size
ttk.Sizegrip(root).pack(side=TK.RIGHT, expand=0, fill=TK.Y, padx=5, pady=5, )

# DEXT Widget
label1 = ttk.Label(labelframe, text="Choose From DEXT.arxml  generate :")  # text=("Choose From DEXT.arxml  generate :")
label1.grid(column=0, row=0)

fileentry_DEXT = ttk.Entry(labelframe)  # ,textvariable=file_path
fileentry_DEXT.grid(column=0, row=1)

button_Brouser_DEXt = ttk.Button(labelframe, text="Browse", command=browseFiles)
button_Brouser_DEXt.grid(column=1, row=1, padx=5)

# RTE Widget
label2 = ttk.Label(labelframe, text=("Choose From RTE.arxml  generate :"))
label2.grid(column=0, row=2)

fileentry_RTE = ttk.Entry(labelframe)  # ,textvariable=file_pat
fileentry_RTE.grid(column=0, row=3)

button_Brouser_RTE = ttk.Button(labelframe, text="Browse")
button_Brouser_RTE.grid(column=1, row=3, padx=5)

# CSV Widget
label3 = ttk.Label(labelframe, text=("Choose folder for csv storage :"))
label3.grid(column=0, row=4)

fileentry_CSV = ttk.Entry(labelframe)
fileentry_CSV.grid(column=0, row=5)

button_Save_csv = ttk.Button(labelframe, text="Save as ", command=save)
button_Save_csv.grid(column=1, row=5, padx=5)

# Bouton quitter
btn_exit = ttk.Button(root, text="Exit", command=exit)

#####################################################
# récupération de fichier
fileentry_DEXT = fileentry_DEXT.get()
fileentry_RTE = fileentry_RTE.get()


#####################################################


def Run():
    # récupération de fichier
    if fileentry_DEXT.get_path() and fileentry_RTE.get_path() and fileentry_CSV.get_path():
        filepath_DEXT = fileentry_DEXT.get_path()
        filepath_RTE = fileentry_RTE.get_path()
        filepath_CSV = fileentry_CSV.get_path()
        
        # call the DiagSpecification Function
        DiagSpec = DiagSpecification()
        
        # Extract DIDS from .axml file and apply Exception list...
        getDIDsFromDEXTfile(filepath_DEXT, DiagSpec.ListOfDIDs)
        DiagSpec.applyExceptionsToDIDs(EXCEPTION_LIST)
        # Export DataRead to cvs file...
        DiagSpec.exportListOfDIDsTocsvFile_DataRead(DIDsCvsFILE1)
        # Export DataReadandWrite to cvs file...
        DiagSpec.exportListOfDIDsTocsvFile_DataReadandWrite(DIDsCvsFILE2)
        
        # **Extract Snap from .axml file and apply Exception list...
        getSnapshotsFromDEXTfile(filepath_DEXT, DiagSpec.ListOfSnapshots)
        # Export Snapshots to cvs file...
        DiagSpec.exportListOfSnapsToCsvFile(SnapCsvFILE)
        
        # **Extract DTC from .axml file and apply Exception list...
        getDTCFromDEXTfile(filepath_DEXT, DiagSpec.ListOfDTCs)
        # Export DTC to cvs file...
        DiagSpec.exportListOfDTCsToCsvFile(DtcCsvFILE)
        
        # Extract Calibration from .axml file and apply Exception list..
        getCalFromRTEfile(filepath_RTE, DiagSpec.listOfCal)
        # Export calibration  to cvs file...
        DiagSpec.exportlistOfCalTocsvFile(CalCsvFILE)
        # do something with the files
    else:
        
        pass


# Labelframe layout inits
labelframe.pack(side=TK.TOP, expand=1, fill=TK.BOTH, padx=5, pady=5)

# Bouton test
btn_Run = ttk.Button(root, text="Run")

# Boutons layout inits
btn_exit.pack(side=TK.RIGHT, padx=20, pady=5)
btn_Run.pack(side=TK.RIGHT, padx=10, pady=5)

root.mainloop()

I've also commented out these imports and other parts of the code that use these as I don't have their codes:

#from DiagSpecification import *
#from DextRteParser import *

Note that I've let be the file_path = TK.StringVar() after a Tkinter window/interface/parent/root has been created.

Here is a fully working code for this:

import tkinter as TK
from tkinter import ttk
from tkinter import filedialog
from tkinter.messagebox import askquestion
from tkinter.filedialog import asksaveasfile

#from DiagSpecification import *
#from DextRteParser import *


def browseFiles(btn):
    # browse file path
    _fpath = filedialog.askopenfilename(initialdir="/", title="Open your document",
                                        filetypes=[('arxml files', '.arxml'), ('all files', '.*')])
    
    if btn == "dext":
        dext_file_path.set(_fpath)
    elif btn == "rte":
        rte_file_path.set(_fpath)


def get_path():
    print(dext_file_path.get())
    return dext_file_path.get()


def save():
    files = [('All Files', '*.*'),
             ('Python Files', '*.py'),
             ('Text Document', '*.txt')]
    file = asksaveasfile(filetypes=files, defaultextension=files)
    csv_storage_path.set(file)
    

def exit():
    answer = askquestion(title='Quit?', message='Really quit?')
    if answer == 'yes':
        root.destroy()


#  create an Interface
root = TK.Tk()
root.title("File explorer")

dext_file_path = TK.StringVar()
rte_file_path = TK.StringVar()
csv_storage_path = TK.StringVar()

labelframe = ttk.LabelFrame(root, text="Selecting files", padding="5px", )

# Size
ttk.Sizegrip(root).pack(side=TK.RIGHT, expand=0, fill=TK.Y, padx=5, pady=5, )

# DEXT Widget
label1 = ttk.Label(labelframe, text="Choose From DEXT.arxml  generate :")  # text=("Choose From DEXT.arxml  generate :")
label1.grid(column=0, row=0)

fileentry_DEXT = ttk.Entry(labelframe,textvariable=dext_file_path)
fileentry_DEXT.grid(column=0, row=1)

button_Brouser_DEXt = ttk.Button(labelframe, text="Browse", command=lambda: browseFiles(btn="dext"))
button_Brouser_DEXt.grid(column=1, row=1, padx=5)

# RTE Widget
label2 = ttk.Label(labelframe, text=("Choose From RTE.arxml  generate :"))
label2.grid(column=0, row=2)

fileentry_RTE = ttk.Entry(labelframe, textvariable=rte_file_path)
fileentry_RTE.grid(column=0, row=3)

button_Brouser_RTE = ttk.Button(labelframe, text="Browse", command=lambda: browseFiles(btn="rte"))
button_Brouser_RTE.grid(column=1, row=3, padx=5)

# CSV Widget
label3 = ttk.Label(labelframe, text=("Choose folder for csv storage :"))
label3.grid(column=0, row=4)

fileentry_CSV = ttk.Entry(labelframe, textvariable=csv_storage_path)
fileentry_CSV.grid(column=0, row=5)

button_Save_csv = ttk.Button(labelframe, text="Save as ", command=save)
button_Save_csv.grid(column=1, row=5, padx=5)

# Bouton quitter
btn_exit = ttk.Button(root, text="Exit", command=exit)

#####################################################
# récupération de fichier
fileentry_DEXT_val = fileentry_DEXT.get()
fileentry_RTE_val = fileentry_RTE.get()


#####################################################


def Run():
    # récupération de fichier
    if fileentry_DEXT.get() and fileentry_RTE.get() and fileentry_CSV.get():
        filepath_DEXT = fileentry_DEXT.get()
        filepath_RTE = fileentry_RTE.get()
        filepath_CSV = fileentry_CSV.get()
        print("It's running!")
        
        # call the DiagSpecification Function
        #DiagSpec = DiagSpecification()
        
        # Extract DIDS from .axml file and apply Exception list...
        #getDIDsFromDEXTfile(filepath_DEXT, DiagSpec.ListOfDIDs)
        #DiagSpec.applyExceptionsToDIDs(EXCEPTION_LIST)
        # Export DataRead to cvs file...
        #DiagSpec.exportListOfDIDsTocsvFile_DataRead(DIDsCvsFILE1)
        # Export DataReadandWrite to cvs file...
        #DiagSpec.exportListOfDIDsTocsvFile_DataReadandWrite(DIDsCvsFILE2)
        
        # **Extract Snap from .axml file and apply Exception list...
        #getSnapshotsFromDEXTfile(filepath_DEXT, DiagSpec.ListOfSnapshots)
        # Export Snapshots to cvs file...
        #DiagSpec.exportListOfSnapsToCsvFile(SnapCsvFILE)
        
        # **Extract DTC from .axml file and apply Exception list...
        #getDTCFromDEXTfile(filepath_DEXT, DiagSpec.ListOfDTCs)
        # Export DTC to cvs file...
        #DiagSpec.exportListOfDTCsToCsvFile(DtcCsvFILE)
        
        # Extract Calibration from .axml file and apply Exception list..
        #getCalFromRTEfile(filepath_RTE, DiagSpec.listOfCal)
        # Export calibration  to cvs file...
        #DiagSpec.exportlistOfCalTocsvFile(CalCsvFILE)
        # do something with the files
    else:
        
        pass


# Labelframe layout inits
labelframe.pack(side=TK.TOP, expand=1, fill=TK.BOTH, padx=5, pady=5)

# Bouton test
btn_Run = ttk.Button(root, text="Run", command=Run)

# Boutons layout inits
btn_exit.pack(side=TK.RIGHT, padx=20, pady=5)
btn_Run.pack(side=TK.RIGHT, padx=10, pady=5)

root.mainloop()

I've changed many things in this. You forgot to specify the command for some Buttons and had commented out some important parts.

The btn in def browseFiles(btn) is the button that is clicked, as both the buttons, button_Brouser_DEXt and button_Brouser_RTE are bound to the same function (it otherwise would set only the first button's text).

I've renamed and added some variables (StringVars):

dext_file_path = TK.StringVar() #the first Entry's text will be stored in this
rte_file_path = TK.StringVar() #the second Entry's text will be stored in this
csv_storage_path = TK.StringVar() #the third Entry's text will be stored in this

Also, I've commented out the code in the Run() function.

See what is the difference between a variable and StringVar() of tkinter, Getting the widget that triggered an Event? and How do I tell which widget triggered an event in Tkinter?.

  • Related