2

I am trying to set value in an path_entry field. Here is the code:

from tkinter import filedialog, ttk,scrolledtext
import tkinter as tk


class GUI(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("SC")
        self.geometry('375x600')
        self.resizable(width=False, height=False)
        

        names = ['Tab 1', 'Tab 2', 'Tab 3', 'Tab 4']
        self.nb = self.create_notebook(names)
        self.menu = self.create_menus()

        self.mainloop()

    def create_notebook(self, names):
        nb = MyNotebook(self, names)
        self.file_path = tk.StringVar()
        nb.pack()

       

        def path_label(parent):
            label = ttk.Label(parent, text="Person file: ").grid(column=0, row=2, padx=10, pady=10)
            return label

        def path_entry(parent):
            
            path = ttk.Entry(parent, width=30, textvariable=self.file_path).grid(column=1, row=2)
            return path

        def browse_button(parent):
            browse = ttk.Button(parent, text="Browse", command=read_csv, width=30).grid(column=1, row=3, padx=10,
                                                                                        pady=10)
            return browse

        def newapp_label(parent):
            label = ttk.Label(parent, text="Press to : ").grid(column=0, row=4, padx=10, pady=10)
            return label

        def newapp_button(parent):
            newapp = ttk.Button(parent, text="Run New Application", width=30).grid(column=1, row=4, padx=10, pady=10)
            return newapp

        def read_csv():
            file = filedialog.askopenfilename()
            if file != None:
                self.file_path.set(file)

        
        # Add some labels to each tab
        tabs = [nb.tabs['Tab 1'],nb.tabs['Tab 2'], nb.tabs['Tab 3'], nb.tabs['Tab 4']]
        for tab in tabs:
            path_label(tab)
            path_entry(tab)
            browse_button(tab)
            newapp_label(tab)
            newapp_button(tab)
        return nb

    
    def create_menus(self):
        menu = tk.Menu(self, tearoff=False)
        self.config(menu=menu)
        subMenu = tk.Menu(menu, tearoff=False)
        menu.add_cascade(label="File", menu=subMenu)
        subMenu.add_separator()
        subMenu.add_command(label='Exit', command=self.destroy)
        return menu


class MyNotebook(ttk.Notebook):
    ''' A customised Notebook that remembers its tabs in a dictionary '''

    def __init__(self, master, names):
        super().__init__(master, width=390, height=470)

        # Create tabs & save them by name in a dictionary
        self.tabs = {}
        for name in names:
            self.tabs[name] = tab = ttk.Frame(self)
            self.add(tab, text=name)


GUI()

So when you click on browse button, it opens a window to load file path in that specific Entry of that Tab. But I noticed the same file/value in all the other tab's Entry field while I want each tab to act as an individual entity. In short, I want to load file path of four different files for each 4 tabs. How can it be possible

Taimorr Mughal
  • 87
  • 1
  • 10

1 Answers1

2

It is because you have used same StringVar self.file_path for all the entries. You should use separate StringVar for each entry instead:

from tkinter.scrolledtext import ScrolledText
...

def create_notebook(self, names):
    nb = MyNotebook(self, names)
    #self.file_path = tk.StringVar()
    nb.pack()

    def path_label(parent):
        label = ttk.Label(parent, text="Person file: ")
        label.grid(column=0, row=2, padx=10, pady=10)
        return label

    def path_entry(parent):
        path = ttk.Entry(parent, width=30, textvariable=parent.file_path)
        path.grid(column=1, row=2)
        return path

    def browse_button(parent):
        browse = ttk.Button(parent, text="Browse", command=lambda:read_csv(parent), width=30)
        browse.grid(column=1, row=3, padx=10, pady=10)
        return browse

    def newapp_label(parent):
        label = ttk.Label(parent, text="Press to : ")
        label.grid(column=0, row=4, padx=10, pady=10)
        return label

    def newapp_button(parent):
        newapp = ttk.Button(parent, text="Run New Application", width=30)
        newapp.grid(column=1, row=4, padx=10, pady=10)
        return newapp

    def add_scrolledtext(parent):
        text = ScrolledText(parent, width=40, height=20)
        text.grid(column=0, row=5, columnspan=2, padx=10, pady=10, sticky='nsew')
        return text

    def read_csv(parent):
        file = filedialog.askopenfilename()
        if file:
            parent.file_path.set(file)
    
    # Add some labels to each tab
    for name in names:
        tab = nb.tabs[name]
        # create a StringVar for this tab
        tab.file_path = tk.StringVar()
        path_label(tab)
        path_entry(tab)
        browse_button(tab)
        newapp_label(tab)
        newapp_button(tab)
        add_scrolledtext(tab)

    return nb

Also you should not write something like label = ttk.Label(...).grid(...) because label is the result of grid(...) which is None. Separate the two functions into two statements:

label = ttk.Label(...)
label.grid(...)

UPDATE: added ScrolledText in each tab.

acw1668
  • 40,144
  • 5
  • 22
  • 34
  • Thank you @acw1668. The answer worked like a charm. One more thing, is it possible to add scrolled text to show some info for each individual tab. Actually I am working on multilogin browser automation with selenium and for that I need to add information after execuation of certain statements to scrolled text. Can you update your answer for that too!. It'll accelerate development a lot. – Taimorr Mughal Jul 24 '20 at 12:53
  • if you find some time, then please have a look at this question. I am completely newbie in tkinter: https://stackoverflow.com/questions/63076650/tkinter-freezes-not-responding-upon-button-pressing-with-multilogin-automation – Taimorr Mughal Jul 24 '20 at 15:51
  • I tried to add text to scrolled text this way. It is adding and updating only one line instead of upserting at the end. add_scrolledtext(parent).insert(INSERT, 'Loading multilogin.....' + '\n') – Taimorr Mughal Jul 25 '20 at 15:05
  • 1
    Did you call the same statement multiple times? – acw1668 Jul 25 '20 at 15:12
  • No, I tried to add END inplace of INSERT for further addition – Taimorr Mughal Jul 25 '20 at 15:49
  • This way `add_scrolledtext(parent).insert(END,'some text at new line'+'\n')` – Taimorr Mughal Jul 25 '20 at 15:52
  • 1
    You can't call `add_scrolledtext(parent)` second time because it will create another scrolledtext. Use the instance of first call to append text. – acw1668 Jul 26 '20 at 02:42