【问题标题】:How to make notebook's each tab as an individual entity?如何将笔记本的每个选项卡作为一个单独的实体?
【发布时间】:2020-11-14 00:55:59
【问题描述】:

我正在尝试在 path_entry 字段中设置值。代码如下:

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()

因此,当您单击浏览按钮时,它会打开一个窗口以在该选项卡的特定条目中加载文件路径。但是我注意到所有其他选项卡的条目字段中的文件/值相同,而我希望每个选项卡都充当单独的实体。 简而言之,我想为每 4 个选项卡加载四个不同文件的文件路径。怎么可能

【问题讨论】:

    标签: python tkinter tkinter-entry


    【解决方案1】:

    这是因为您对所有条目都使用了相同的StringVar self.file_path。您应该为每个条目使用单独的StringVar

    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
    

    另外你不应该写像label = ttk.Label(...).grid(...)这样的东西,因为labelgrid(...)的结果None。将两个函数分成两条语句:

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

    更新:在每个标签中添加了ScrolledText

    【讨论】:

    • 谢谢@acw1668。答案就像一个魅力。还有一件事,是否可以添加滚动文本以显示每个单独选项卡的一些信息。实际上,我正在使用 selenium 进行多登录浏览器自动化,为此我需要在执行某些语句到滚动文本后添加信息。你也可以更新你的答案吗!它将大大加快开发速度。
    • 如果你有时间,那么请看看这个问题。我是 tkinter 的新手:stackoverflow.com/questions/63076650/…
    • 我尝试以这种方式将文本添加到滚动文本中。它只添加和更新一行,而不是最后插入。 add_scrolledtext(parent).insert(INSERT, 'Loading multilogin.....' + '\n')
    • 你是否多次调用同一个语句?
    • 您不能第二次调用add_scrolledtext(parent),因为它会创建另一个滚动文本。使用第一次调用的实例来追加文本。
    猜你喜欢
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多