单击按钮并在框架中打开内容(框架中的直接方式和导入脚本.py 的方式)

Click on a button and open the content in a frame (direct way in frame and way with import script .py)

我想单击一个按钮并在屏幕的其余部分(灰色所在的位置)查看其内容,但要通过框架,而不是跨过 canvas。

我需要 2 个示例,但请将其应用于我的代码:

我需要这两个简单的示例,因为对于每一帧(因此对于每个按钮)我都有足够长的代码并且我想以有序和干净的方式管理它。所以我想测试这两个示例,但应用于我的代码。

我以前在网上和 Whosebug 上看过示例,但我无法将自己应用到我的代码中。你能帮我使用我的代码吗?

(我的代码在下面)

from tkinter import messagebox
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk, Image

root = tk.Tk()
root.title("xxxx")
root.geometry("1920x1080+0+0")
root.config(bg="#f0f0f0")
root.state("normal")

topbar = tk.Frame(root, background="#e10a0a", height=43)
topbar.pack(fill='x') # use pack() instead of place()

leftbar = tk.Frame(root, width=250, background="white")
leftbar.pack(side='left', fill='y') # use pack() instead of place()
leftbar.pack_propagate(0) # disable size auto-adjustment

def clicked(btn):
    for w in leftbar.winfo_children():
        w['bg'] = 'white' if w is not btn else 'yellow'

button1 = tk.PhotoImage(file="/image.png")
btn1 = tk.Button(leftbar, image=button1, borderwidth=0, highlightthickness=0,
                 bg="white", text="aaaaa", foreground='green', compound='left', anchor='w')
btn1.pack(fill='x') # use pack() instead of place()
btn1['command'] = lambda: clicked(btn1)

button2 = tk.PhotoImage(file="/image.png")
btn2 = tk.Button(leftbar, image=button2, borderwidth=0, highlightthickness=0,
                 bg="white", text="bbbbb", foreground='green', compound='left', anchor='w')
btn2.pack(fill='x') # use pack() instead of place()
btn2['command'] = lambda: clicked(btn2)

root.mainloop()

我建议您通过 subclassing tk.Frame 创建一个单独的 class 并在那里实现选项卡更改的逻辑。

import tkinter as tk
from PIL import ImageTk, Image

class TabBar(tk.Frame):

    def __init__(self, *args, **kwargs):
        super(TabBar, self).__init__(*args, **kwargs)

        self.side_bar = tk.Frame(self, background="white")
        # self.side_bar.place(relx=0, rely=0, relheight=1, relwidth=0.2)
        self.side_bar.pack(side="left", fill="both")

        self.tabs = {}
        self.active_tab = None

        self.active_color = "yellow"
        self.default_color = "grey"

    def addTab(self, name, widget, image: ImageTk.PhotoImage=None):
        
        btn = tk.Button(self.side_bar, text=name, image=image, 
                    compound="left", command=lambda: self.setActive(name),
                    bg=self.default_color, width=20, relief="flat")
        btn.pack(fill="x", anchor="n")

        self.tabs[name] = [btn, widget]
        
        if self.active_tab is None:
            self.setActive(name)
    
    def setActive(self, name):
        if self.active_tab:
            # self.tabs[self.active_tab][1].place_forget()
            self.tabs[self.active_tab][1].pack_forget()
            self.tabs[self.active_tab][0].config(bg=self.default_color)
        
        self.tabs[name][0].config(bg=self.active_color)
        # self.tabs[name][1].place(relx=0.2, rely=0, relheight=1, relwidth=1)
        self.tabs[name][1].pack(side="left", expand=True, fill="both")
        
        self.active_tab = name

    def removeTab(self, name):
        self.tabs.pop(name)

在上面的代码中,您可以使用addTab方法添加选项卡,名称参数对于每个选项卡应该是唯一的,因为名称被用作字典中的键。您可以选择将 PhotoImage 实例传递给图像参数以显示图像。

您可以将以上class放在同一个文件或不同的文件中并导入。

用法示例:

root = tk.Tk()
root.config(bg="#f0f0f0")

imag = Image.open("image.png")
imagtk = ImageTk.PhotoImage(imag)

tab_bar = TabBar(root)
tab_bar.pack(expand=True, fill="both")


frame = tk.Frame(tab_bar)
button = tk.Button(frame, text="Click Me")
button.pack()

tab_bar.addTab("aaaa", tk.Label(tab_bar, text="contents"), imagtk)
tab_bar.addTab("bbbb", frame)

root.mainloop()

(注意:您需要将 tab_bar 作为您的小部件的父级传递给您想要放置在选项卡中的小部件)

输出:

你可以使用一个ttk.Notebook来实现你想要的:

import tkinter as tk
from tkinter import ttk
from PIL import ImageTk

# define classes for each page

class Page1(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
        tk.Label(self, text='Hello', font='Arial 64 bold').pack(fill='both', expand=1)

class Page2(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
        tk.Label(self, text='Python is awesome', font='Times 24 bold', bg=self['bg']).pack()
        self.logo = ImageTk.PhotoImage(file='images/python-logo.png')
        tk.Label(self, image=self.logo, bg=self['bg']).pack(fill='both', expand=1)

root = tk.Tk()
root.geometry('640x480')

topbar = tk.Frame(root, bg='#e10a0a', height=43)
topbar.pack(fill='x')

style = ttk.Style()
style.theme_use('default') # select a theme that allows configuration of ttk.Notebook
# put the tabs at the left with white background
style.configure('TNotebook', tabposition='wn', background='white', tabmargins=0)
# configure tab with white background initially, yellow background when selected
style.configure('TNotebook.Tab', background='white', width=10, focuscolor='yellow', borderwidth=0)
style.map('TNotebook.Tab', background=[('selected', 'yellow')])

nb = ttk.Notebook(root)
nb.pack(fill='both', expand=1)

img = ImageTk.PhotoImage(file='images/div2.png')

page1 = Page1(nb)
page2 = Page2(nb, bg='pink', bd=0)

nb.add(page1, text='aaaaa', image=img, compound='left')
nb.add(page2, text='bbbbb', image=img, compound='left')

root.mainloop()

输出:


你也可以将每个页面的class定义放到外部文件中,例如Page1page1.pyPage2page2.py。然后将它们导入主脚本:

import tkinter as tk
from tkinter import ttk
from PIL import ImageTk
from page1 import Page1
from page2 import Page2

root = tk.Tk()
root.geometry('640x480')

topbar = tk.Frame(root, bg='#e10a0a', height=43)
topbar.pack(fill='x')

style = ttk.Style()
style.theme_use('default') # select a theme that allows configuration of ttk.Notebook
# put the tabs at the left with white background
style.configure('TNotebook', tabposition='wn', background='white', tabmargins=0)
# configure tab with white background initially, yellow background when selected
style.configure('TNotebook.Tab', background='white', width=10, focuscolor='yellow', borderwidth=0)
style.map('TNotebook.Tab', background=[('selected', 'yellow')])

nb = ttk.Notebook(root)
nb.pack(fill='both', expand=1)

img = ImageTk.PhotoImage(file='images/div2.png')

page1 = Page1(nb)
page2 = Page2(nb, bg='pink', bd=0)

nb.add(page1, text='aaaaa', image=img, compound='left')
nb.add(page2, text='bbbbb', image=img, compound='left')

root.mainloop()

page1.py

import tkinter as tk

class Page1(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
        tk.Label(self, text='Hello', font='Arial 64 bold').pack(fill='both', expand=1)

page2.py

import tkinter as tk
from PIL import ImageTk

class Page2(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
        tk.Label(self, text='Python is awesome', font='Times 24 bold', bg=self['bg']).pack()
        self.logo = ImageTk.PhotoImage(file='images/python-logo.png')
        tk.Label(self, image=self.logo, bg=self['bg']).pack(fill='both', expand=1)