0

I am building my first GUI using tkinter and have come up against some problems. To make the code more modular, I am using an object-oriented approach, as seen in the code below. The basic idea is that I have defined classes for the DataFrame, MetaFrame and SaveFrame, which are all instantiated within the OptionsFrame, which then is instantiated within the MainWindow.

import tkinter as tk
from tkinter import ttk


class DataFrame(ttk.Frame):
    def __init__(self, main, *args, **kwargs):
        super().__init__(main, *args, **kwargs)
        # data frame elements
        self.data_label = ttk.Label(self, text="Add Data:")

        self.labelled_tweets_label = ttk.Label(self, text="Labelled-Tweets: ")
        self.labelled_tweets_button = ttk.Button(self, text="Browse")

        self.places_label = ttk.Label(self, text="Places: ")
        self.places_button = ttk.Button(self, text="Browse")

        self.plots_label = ttk.Label(self, text="Plots Path: ")
        self.plots_button = ttk.Button(self, text="Browse")

        self.submit_button = ttk.Button(self, text="Submit")

        # data frame layout
        self.data_label.grid(row=0, column=0, columnspan=2, pady=10)
        self.labelled_tweets_label.grid(row=1, column=0)
        self.labelled_tweets_button.grid(row=1, column=1)
        self.places_label.grid(row=2, column=0)
        self.places_button.grid(row=2, column=1)
        self.plots_label.grid(row=3, column=0)
        self.plots_button.grid(row=3, column=1)
        self.submit_button.grid(row=4, column=0, columnspan=2, pady=10)


class MetaFrame(ttk.Frame):
    ...


class SaveFrame(ttk.Frame):
    ...


class OptionsFrame(ttk.Frame):
    def __init__(self, main, *args, **kwargs):
        super().__init__(main, *args, **kwargs)
        # options frame components
        self.data_frame = DataFrame(self)
        self.horiz1 = ttk.Separator(self, orient="horizontal")
        self.meta_frame = MetaFrame(self)
        self.horiz2 = ttk.Separator(self, orient="horizontal")
        self.save_frame = SaveFrame(self)

        # options frame layout
        self.data_frame.grid(row=0, column=0)
        self.horiz1.grid(row=1, column=0, sticky="ew", pady=30)
        self.meta_frame.grid(row=2, column=0)
        self.horiz2.grid(row=3, column=0, sticky="ew", pady=30)
        self.save_frame.grid(row=4, column=0, sticky="s")

class MainWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry("800x600")
        self.resizable(False, False)

        # configuration
        self.columnconfigure(index=0, weight=1)
        self.columnconfigure(index=1, weight=2)

        # main frames
        self.options_frame = OptionsFrame(self, width=400, height=600, borderwidth=1)
        self.vert = ttk.Separator(self, orient="vertical")
        # main layout

        self.options_frame.grid(row=0, column=0)
        self.vert.grid(row=0, column=1, sticky="ns")

def main():
    root = MainWindow()
    root.mainloop()

The layout can be seen in the following image.

GUI Layout

This is the basic layout I want within the OptionsFrame. My confusion lies with creating filedialog methods for the three file browsing buttons within the DataFrame. I understand how to use the filedialog class to return the path to a given file, but then this value is restricted to be in the scope of the DataFrame.

I have a back-end that is already developed which requires these file paths, so ideally I would like to access them from the main() function. How is this possible?

Thanks

Bazoya
  • 23
  • 3
  • 1
    If the three filenames inside `DataFrame` are instance variables, for example `self.file1`, `self.file2` and `self.file3`, then you can use `root.options_frame.data_frame.file1` to access the first filename. However it is better to create functions or properties to access those filenames in each class. – acw1668 Jul 21 '22 at 09:04
  • I've had decent luck sharing data between classes using the approach shown in [this answer](https://stackoverflow.com/questions/33646605/how-to-access-variables-from-different-classes-in-tkinter). But @acw1668's answer is more straightforward if your app isn't especially large or complex! – JRiggles Jul 21 '22 at 14:07

0 Answers0