Search code examples
pythontkinterargparse

How do I pass arguments from tkinter function to external module?


I would like to call an external module (python script) from a tkinter button. My external module text_parser.py requires a single argument and looks like this:

import argparse


def main(filename):

    # Parse arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('filename', type=str)
    args = parser.parse_args()

    # Parse text

My button code looks like this:

from tkinter import *
from tkinter import filedialog

# Import text parser script
from text_parser import *


def browse_files():
    global filename
    filename = filedialog.askopenfilename()


def parse_text():
    if __name__ == '__main__':
        main(filename)


# Create window
window = Tk()

# Define Select TXT button
select_TXT_button = Button(window, text='Select TXT', command=browse_files)
select_TXT_button.pack()

# Define Parse TXT button
parse_TXT_button = Button(window, text='Parse TXT', command=parse_text)
parse_TXT_button.pack()

# Enter event loop
window.mainloop()

When running the button code gui.py, the Select TXT button works without error. However, subsequently clicking the Parse TXT button results in the following error:

usage: gui.py [-h] filename
gui.py: error: the following arguments are required: filename

Process finished with exit code 2

It appears that filename is (unexpectedly) not passing to the text_parser module. How can I pass arguments to external modules from tkinter functions?


Solution

  • Arguments can be passed by making changes to both text_parser.py and the button code gui.py:

    text_parser.py: move argparse out of main() as @acw1668 suggested:

    def main(filename):
        print(f'Parsing: {filename}')
        # Parse text
    
    
    if __name__ == '__main__':
        import argparse
    
        # Parse filename from arguments
        parser = argparse.ArgumentParser()
        parser.add_argument('filename', type=str)
        args = parser.parse_args()
        filename = vars(args)['filename']
    
        main(filename)
    

    gui.py: similarly, remove if __name__ == '__main__'::

    from tkinter import *
    from tkinter import filedialog
    
    # Import text parser script
    from text_parser import *
    
    
    def browse_files():
        global filename
        filename = filedialog.askopenfilename()
    
    
    def parse_text():
        main(filename)
    
    
    # Create window
    window = Tk()
    
    # Define Select TXT button
    select_TXT_button = Button(window, text='Select TXT', command=browse_files)
    select_TXT_button.pack()
    
    # Define Parse TXT button
    parse_TXT_button = Button(window, text='Parse TXT', command=parse_text)
    parse_TXT_button.pack()
    
    # Enter event loop
    window.mainloop()