【问题标题】:Adding notebook tabs in tkinter - how do I do it with a class-based structure? (Python 3)在 tkinter 中添加笔记本选项卡 - 如何使用基于类的结构? (Python 3)
【发布时间】:2017-06-25 10:10:03
【问题描述】:

我编写了一个 tkinter 应用程序,它在两个框架上显示了小部件,类似于这个示例,它成功运行。

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Example")

notebook = ttk.Notebook(root)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
notebook.add(frame1, text="Frame One")
notebook.add(frame2, text="Frame Two")
notebook.pack()

#(The labels are examples, but the rest of the code is identical in structure). 

labelA = ttk.Label(frame1, text = "This is on Frame One")
labelA.grid(column=1, row=1)

labelB = ttk.Label(frame2, text = "This is on Frame Two")
labelB.grid(column=1, row=1)

root.mainloop()

我决定我应该尝试重组程序以使用一个类(我承认我不是很熟悉)。但是,我不确定我应该怎么做才能让小部件出现在不同的框架上(其他一切正常)。例如,以下代码会产生“TypeError: init() 采用 1 到 2 个位置参数,但给出了 3 个”。所以大概我需要用一个额外的参数进行初始化,但我不确定笔记本将如何工作,或者这是否是我应该采取的方法。 (如果从标签中删除“frame1”和“frame2”参数,程序将运行,但是,它将在两个框架上显示相同的内容)。

from tkinter import *
from tkinter import ttk

class MainApplication(ttk.Frame):
    def __init__(self, parent):
        ttk.Frame.__init__(self, parent)

        self.labelA = ttk.Label(self, frame1, text = "This is on Frame One")
        self.labelA.grid(column=1, row=1)

        self.labelB = ttk.Label(self, frame2, text = "This is on Frame Two")
        self.labelB.grid(column=1, row=1)

root = Tk()
root.title("Example")
notebook = ttk.Notebook(root)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
notebook.add(frame1, text="Frame One")
notebook.add(frame2, text="Frame Two")
notebook.pack()
MainApplication(root).pack()
root.mainloop()

我对解决方案感兴趣,但我也有兴趣了解该类与独立小部件相比有何不同。

【问题讨论】:

  • 请提供minimal reproducible example。脱离上下文显示代码块并不是很有用。
  • @Bryan Oakley 修改
  • 我刚刚观看了一个 youtube 视频,我认为它准确地描述了您正在寻找的内容。这是系列link 的链接,我认为它在前几个视频中有所介绍。这家伙创建了一个类,它本质上将为您的多个窗口创建多个选项卡。
  • @Joe 这似乎可行,尽管它相对复杂且不使用笔记本。当然应该有一种简单的方法将我的第一个示例转换为一个类。

标签: python python-3.x tkinter


【解决方案1】:

这是将应用程序概括为一个类的一种方法。你想消除重复的代码。

from tkinter import *
from tkinter import ttk

class Notebook:

    def __init__(self,title):
        self.root = Tk()
        self.root.title(title)
        self.notebook = ttk.Notebook(self.root)

    def add_tab(self,title,text):
        frame = ttk.Frame(self.notebook)
        self.notebook.add(frame,text=title)
        label = ttk.Label(frame,text=text)
        label.grid(column=1,row=1)
        self.notebook.pack()

    def run(self):
        self.root.mainloop()

nb = Notebook('Example')
nb.add_tab('Frame One','This is on Frame One')
nb.add_tab('Frame Two','This is on Frame Two')
nb.run()

【讨论】:

    【解决方案2】:

    我建议您将笔记本中的不同框架拆分为单独的文件。 我使用 from tab2 import * 因为我希望它保留在命名空间中而不添加文件/类前缀,即。我不想写:tab1.Tab1(notebook)

    main.py

    import tkinter as tk
    from tkinter import ttk
    
    from tab1 import *
    from tab2 import *    
    
    class MainApplication(tk.Frame):
      def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
    
        notebook = ttk.Notebook(parent)
    
        Tab1frame = Tab1(notebook)
        Tab2frame = Tab2(notebook)
    
        notebook.add(Typ1frame, text='TAB1')
        notebook.add(Typ2frame, text='TAB2')
        notebook.pack()
    
    if __name__ == "__main__":
        root = tk.Tk()
        MainApplication(root).pack(side="top", fill="both", expand=True)
        root.mainloop()
    

    tab1.py

    import tkinter as tk
    from tkinter import ttk
    
    class Typ14(tk.Frame):
      def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        shell_frame=tk.LabelFrame(self, text="Sample Label Frame", padx=5,pady=5)
        shell_frame.grid(row=0,column=0,padx=5,pady=5)
    

    【讨论】:

      【解决方案3】:

      为确保您的代码清晰且有目的,您应该为您的主应用程序创建一个类,并为每个选项卡创建一个类。您需要将选项卡类分隔到单独的文件中,但如果您正在与其他开发人员合作,这将符合您的最大利益。

      下面的代码显示您的代码重新格式化为具有 3 个类:1 个用于主应用程序 (MainApplication),2 个用于每个选项卡(Frame1 和 Frame2)。此外,为了便于参考,我已经 imported tkinter as tk

      import tkinter as tk
      from tkinter import ttk
      
      class MainApplication(tk.Tk):
          def __init__(self):
              super().__init__()
      
              self.title("Example")
              self.geometry('300x300')
      
              self.notebook = ttk.Notebook(self)
      
              self.Frame1 = Frame1(self.notebook)
              self.Frame2 = Frame2(self.notebook)
      
              self.notebook.add(self.Frame1, text='Frame1')
              self.notebook.add(self.Frame2, text='Frame2')
      
              self.notebook.pack()
      
      class Frame1(ttk.Frame):
          def __init__(self, container):
              super().__init__()
      
              self.labelA = ttk.Label(self, text = "This is on Frame One")
              self.labelA.grid(column=1, row=1)
      
      class Frame2(ttk.Frame):
          def __init__(self, container):
              super().__init__()
      
              self.labelB = ttk.Label(self, text = "This is on Frame Two")
              self.labelB.grid(column=1, row=1)
      
      if __name__ == '__main__':
          app = MainApplication()
          app.mainloop()
      

      您可以想象,这将允许您创建其他类以将框架添加到您的选项卡类。下面的代码显示了对上面class Frame1 的更改,以及添加的class Frame1FrameA 就是这样做的。

      class Frame1(ttk.Frame):
          def __init__(self, container):
              super().__init__(container)
      
              self.labelA = ttk.Label(self, text = "This is on Frame One")
              self.labelA.grid(column=1, row=1)
      
              self.frame = Frame1FrameA(self)
              self.frame.grid(row=1, columnspan=2)
      
      class Frame1FrameA(ttk.Frame):
          def __init__(self, container):
              super().__init__(container)
      
              self.LabelA = ttk.Label(self, text="LabelA in FrameA in tab Frame1")
              self.LabelA.grid(column=0, row=0)
      
              self.LabelB = ttk.Label(self, text="LabelB in FrameA in tab Frame1")
              self.LabelB.grid(column=1, row=0)
      

      【讨论】:

        猜你喜欢
        • 2018-04-05
        • 2021-04-27
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 2022-06-27
        • 1970-01-01
        相关资源
        最近更新 更多