【问题标题】:Reuse Tkinter code, within different windows在不同的窗口中重用 Tkinter 代码
【发布时间】:2021-11-03 11:22:15
【问题描述】:

我有一个包含按钮的 GUI,单击这些按钮会打开一个新窗口,其中的框架与根目录相同。它还从视图中撤回根窗口。我使用“纸笔”方法来确定框架的位置。

我想在整个 GUI 中重复使用相同的框架布局,因为我计划增加按钮的数量,但不想重复相同的代码。 以更高效的方式组织代码的最佳方法是什么?

这是我的脚本:

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
root.geometry('')
root.resizable(False, False)

# Functions
def exitApplication():
    MsgBox = messagebox.askquestion('Exit Application', 'Are you sure you want to exit?', icon='warning')
    if MsgBox == 'yes':
        root.destroy()

def hide(window):
    window.withdraw()

def show(window):
    window.deiconify()
    window.update()

def button1Window():
    hide(root)
    global icon
    btn1Win = tk.Toplevel(root)
    btn1Win.title('Button 1')
    btn1Win.geometry('')

    # Frames
    topFrm = tk.Frame(btn1Win)
    topFrm.pack(fill=tk.BOTH)

    middleFrm = tk.Frame(btn1Win, pady=10, highlightbackground="black", highlightthickness=1)
    middleFrm.pack(fill=tk.BOTH)

    bottomFrm = tk.Frame(btn1Win)
    bottomFrm.pack(fill=tk.BOTH)

    endFrm = tk.Frame(btn1Win)
    endFrm.pack(fill=tk.BOTH)

    # Labels
    btn1WinLbl = tk.Label(topFrm, text='Button 1 Window')
    btn1WinLbl.pack()

    firstLbl = tk.Label(middleFrm, text='This is the content for Button 1. '
                                        '\n More information will be added in the future.')
    firstLbl.grid(row=0, columnspan=3)

    versionLbl = tk.Label(endFrm, text='Version 0.1 2021', )
    versionLbl.config(font=('Times New Roman', 5))
    versionLbl.pack(side=tk.RIGHT)

    # Buttons
    tk.Button(btn1Win, text='Back to Home', command=lambda:[show(root), btn1Win.destroy()]).pack()
    btn1Win.protocol("WM_DELETE_WINDOW", exitApplication)

def button2Window():
    hide(root)
    global icon
    btn2Win = tk.Toplevel(root)
    btn2Win.title('Button 2')
    btn2Win.geometry('')

    # Frames
    topFrm = tk.Frame(btn2Win)
    topFrm.pack(fill=tk.BOTH)

    middleFrm = tk.Frame(btn2Win, pady=10, highlightbackground="black", highlightthickness=1)
    middleFrm.pack(fill=tk.BOTH)

    bottomFrm = tk.Frame(btn2Win)
    bottomFrm.pack(fill=tk.BOTH)

    endFrm = tk.Frame(btn2Win)
    endFrm.pack(fill=tk.BOTH)

    # Labels
    btn1WinLbl = tk.Label(topFrm, text='Button 2 Window')
    btn1WinLbl.pack()

    firstLbl = tk.Label(middleFrm, text='This is the content for Button 2. '
                                        '\n This is for Vegetables.'
                                        '\n More Vegetables will be added in the future.')
    firstLbl.grid(row=0, columnspan=3)

    versionLbl = tk.Label(endFrm, text='Version 0.1 2021', )
    versionLbl.config(font=('Times New Roman', 5))
    versionLbl.pack(side=tk.RIGHT)

    # Buttons
    tk.Button(btn2Win, text='Back to Home', command=lambda:[show(root), btn2Win.destroy()]).pack()
    btn2Win.protocol("WM_DELETE_WINDOW", exitApplication)

def button3Window():
    hide(root)
    global icon
    btn3Win = tk.Toplevel(root)
    btn3Win.title('Button 3')
    btn3Win.geometry('')

    # Frames

    topFrm = tk.Frame(btn3Win)
    topFrm.pack(fill=tk.BOTH)

    middleFrm = tk.Frame(btn3Win, pady=10, highlightbackground="black", highlightthickness=1)
    middleFrm.pack(fill=tk.BOTH)

    bottomFrm = tk.Frame(btn3Win)
    bottomFrm.pack(fill=tk.BOTH)

    endFrm = tk.Frame(btn3Win)
    endFrm.pack(fill=tk.BOTH)

    # Labels
    btn3WinLbl = tk.Label(topFrm, text='Button 3 Window')
    btn3WinLbl.pack()

    firstLbl = tk.Label(middleFrm, text='This is the content for Button 3. '
                                        '\n This is for Fruit'
                                        '\n More Fruit will be added in the future.')
    firstLbl.grid(row=0, columnspan=3)

    versionLbl = tk.Label(endFrm, text='Version 0.1 2021', )
    versionLbl.config(font=('Times New Roman', 5))
    versionLbl.pack(side=tk.RIGHT)

    # Buttons
    tk.Button(btn3Win, text='Back to Home', command=lambda:[show(root), btn3Win.destroy()]).pack()
    btn3Win.protocol("WM_DELETE_WINDOW", exitApplication)

# Create Frames first, and fill with widgets later
topFrm = tk.Frame(root)
topFrm.pack(fill=tk.BOTH)

middleFrm = tk.Frame(root, pady=10, highlightbackground="black", highlightthickness=1)
middleFrm.pack(fill=tk.BOTH)

bottomFrm = tk.Frame(root)
bottomFrm.pack(fill=tk.BOTH)

endFrm = tk.Frame(root)
endFrm.pack(fill=tk.BOTH)

# Label widgets
titleLbl = tk.Label(topFrm, text='Homepage')
titleLbl.pack()

firstLbl = tk.Label(middleFrm, text='Choose one of the following options.\n A new window will open.')
firstLbl.grid(row=0, columnspan=4)

versionLbl = tk.Label(endFrm, text='Version 0.1 2021',)
versionLbl.config(font=('Times New Roman', 5))
versionLbl.pack(side=tk.RIGHT)

# Button widgets
Btn1 = tk.Button(middleFrm, text="Button 1", width=10, height=2,
                       command=button1Window).grid(row=1, column=0, padx=3, pady=3)

Btn2 = tk.Button(middleFrm, text="Button 2", width=10, height=2,
                       command=button2Window).grid(row=1, column=1, padx=3, pady=3)

Btn3 = tk.Button(middleFrm, text="Button 3", width=10, height=2,
                       command=button3Window).grid(row=1, column=3, padx=3, pady=3)

exitBtn = tk.Button(bottomFrm, text="Exit", width=10, height=1, command=exitApplication,
                         ).pack(padx=5, pady=5)

# Call exitApplication function if Red X clicked
root.protocol("WM_DELETE_WINDOW", exitApplication)
root.mainloop()

【问题讨论】:

    标签: python user-interface tkinter


    【解决方案1】:

    为框架创建一个新函数会有所帮助,例如,添加常​​用的东西,并在func中传递文本(这个函数也可以更简单)-

    def create_frame_layout(
        n,win_lbl,content): # Added some variables to be passed
        hide(root)
    
        container = tk.Toplevel(root)
        container.title(f'Button {n}')
        container.geometry('')
    
        topFrm = tk.Frame(container)
        topFrm.pack(fill=tk.BOTH)
    
        middleFrm = tk.Frame(container, pady=10, highlightbackground="black", highlightthickness=1)
        middleFrm.pack(fill=tk.BOTH)
    
        bottomFrm = tk.Frame(container)
        bottomFrm.pack(fill=tk.BOTH)
    
        endFrm = tk.Frame(container)
        endFrm.pack(fill=tk.BOTH)
    
        tk.Button(container, text='Back to Home', command=lambda:[show(root), container.destroy()]).pack()
        container.protocol("WM_DELETE_WINDOW", exitApplication)
    
        btn1WinLbl = tk.Label(topFrm, text=win_lbl)
        btn1WinLbl.pack()
    
        firstLbl = tk.Label(middleFrm, text=content)
        firstLbl.grid(row=0, columnspan=3)
    
        versionLbl = tk.Label(endFrm, text='Version 0.1 2021', )
        versionLbl.config(font=('Times New Roman', 5))
        versionLbl.pack(side=tk.RIGHT)
    

    然后只需调用所需文本的函数 -

    def button1Window():
        global icon
        
        num = 1
        win_lbl = 'Button 1 Window' # Just provide the text you want
        btn_content = 'This is the content for Button 1.\n More information will be added in the future.'
    
        create_frame_layout(num,win_lbl,btn_content)
    
    def button2Window():
        global icon
        
        num = 2 
        win_lbl = 'Button 2 Window' # Just provide the text you want
        btn_content = 'This is the content for Button 2.\n This is for Vegetables.\n More Vegetables will be added in the future.'
    
        create_frame_layout(num,win_lbl,btn_content) # etc...
    

    【讨论】:

    • 注意:我所做的只是一个例子,你可以通过使btn1Win = tk.Toplevel(root) 也通用来使其更简单,但这很复杂
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    相关资源
    最近更新 更多