从笔记本中的其他选项卡访问变量

Accessing variables from other tab in notebook

大家好, 我在这个组的最后一个问题没有成功,因为我的代码太长了。 我现在已将我的代码降至最低并添加了屏幕截图。我希望这次一切都清楚而不是混乱。 我的问题是:如何检查 Tab1 中的变量“val”是否小于 5。 如果不是,则 Tab1 中的框架和按钮必须为灰色且已禁用。该按钮不得执行任何操作。 问题是我已经将“val”定义为全局的,但它仍然带来“val”未知的错误信息。 知道为什么 Tab1 中不知道“val”吗?

# Filename: Tab1.py
from tkinter import *

def gen_t1(frame):
    global val
  
    f = LabelFrame(frame, text='f', bg='lightgreen')
    f.pack(expand=True, fill='both')

    b1 = Button(f, text='B1').pack()

##    if val < 5:
##        f_enabled = 'disabled'
##        f['bg'] = 'lightgray'
##    else:
##        f_enabled = 'normal'
##        f['bg'] = 'lightgreen'

# Filename: Tab2.py
from tkinter import *

def gen_t2(frame):
    def getValue(event):
        global val
        val = ent.get()
        print(val)

    lbl = Label(frame, text='Val').pack()

    ent = Entry(frame)
    ent.pack()
    ent.insert(0, '2')
  
    ent.bind('<Return>', getValue)

# Filename: TabTop
from tkinter import *
from tkinter import ttk

from Tab1 import gen_t1
from Tab2 import gen_t2

firstTime1 = 1
firstTime2 = 1
root = Tk()
root.title('Tab-Tester')
root.geometry('300x200')

nb = ttk.Notebook(root)
tab1 = Frame(nb)
tab2 = Frame(nb)
  
nb.add(tab1, text ='Tab 1')
nb.add(tab2, text ='Tab 2')
nb.pack(expand = 1, fill ="both")

def on_tab_change(event):
    global firstTime1, firstTime2
  
    tab = event.widget.tab('current','text')
    if tab == 'Tab 1':
        print('Tab 1')
        if firstTime1 == 1:
            gen_t1(tab1)
            firstTime1 = 0
    elif tab == 'Tab 2':
        print('Tab 2')
        if firstTime2 == 1:
            gen_t2(tab2)
            firstTime2 = 0
nb.bind('<<NotebookTabChanged>>', on_tab_change)

root.mainloop()

我认为您应该使用面向对象的方式来构建您的 GUI。根据我对您情况的了解,这是我建议的解决方案:

Tab1.py

import tkinter as tk
from tkinter import ttk

class Button_page(ttk.Frame):
    """This will contain what is going to be shown on the first tab."""

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

        self.variable_to_check = variable_to_check
        self.variable_to_check.trace('w', lambda *args: self.update_background())

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.internal_style = ttk.Style()
        self.internal_style.configure('Tab1.TLabelframe', background='lightgreen')
        self.internal_style.configure('Tab1.TLabelframe.Label', background='lightgreen')

        self.f = ttk.LabelFrame(self, text='f', style='Tab1.TLabelframe')
        self.f.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
        self.f.columnconfigure(0, weight=1)
        self.f.rowconfigure(0, weight=0)

        self.b1 = ttk.Button(self.f, text='B1')
        self.b1.grid(column=0, row=0, sticky=(tk.N,))

    def update_background(self):
        new_value_string = self.variable_to_check.get()
        try:
            new_value = int(new_value_string)
        except (ValueError):
            new_value = 0

        if new_value < 5:
            self.internal_style.configure('Tab1.TLabelframe', background='lightgray')
            self.internal_style.configure('Tab1.TLabelframe.Label', background='lightgray')
            self.b1.config(state=tk.DISABLED)
        else:
            self.internal_style.configure('Tab1.TLabelframe', background='lightgreen')
            self.internal_style.configure('Tab1.TLabelframe.Label', background='lightgreen')
            self.b1.config(state=tk.NORMAL)
           

Tab2.py

import tkinter as tk
from tkinter import ttk

class Entry_page(ttk.Frame):
    """This will contain what is going to be shown on the second tab."""

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

        self.entry_value = tk.StringVar()

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=0)

        value_label = ttk.Label(self, text='Val')
        value_label.grid(column=0, row=0)

        value_entry = ttk.Entry(self, textvariable=self.entry_value)
        value_entry.grid(column=0, row=1)

TabTop.py

import tkinter as tk
from tkinter import ttk

import Tab1
import Tab2

root = tk.Tk()
root.title('Tab-Tester')
root.geometry('300x200')

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

nb = ttk.Notebook(root)
t2 = Tab2.Entry_page(nb)
t1 = Tab1.Button_page(variable_to_check=t2.entry_value, master=nb)
t2.entry_value.set(2)

nb.add(t1, text='Tab 1')
nb.add(t2, text='Tab 2')
nb.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
nb.columnconfigure(0, weight=1)
nb.rowconfigure(0, weight=1)

root.mainloop()

要同步两个选项卡之间的信息,您需要一个连接在 ttk.Entry 之间的 tkinter variable 实例和一个回调函数,该函数将在 [=14= 的内容时触发]的改变了。

我知道关于 tkinter 的文档不多。我会推荐:


我们可以更加面向对象:

TabTop2.py

import tkinter as tk
from tkinter import ttk

import Tab1
import Tab2

class Tab_pages_application(tk.Tk):

    def __init__(self, title, size, value_page, action_page, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.title(title)
        self.geometry(size)

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        nb = ttk.Notebook(self)
        t2 = value_page(nb)
        t1 = action_page(variable_to_check=t2.entry_value, master=nb)
        t2.entry_value.set(2)

        nb.add(t1, text='Tab 1')
        nb.add(t2, text='Tab 2')
        nb.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
        nb.columnconfigure(0, weight=1)
        nb.rowconfigure(0, weight=1)

if __name__ == '__main__':
    root = Tab_pages_application('Tab-Tester', '300x200', Tab2.Entry_page, Tab1.Button_page)
    root.mainloop()

这是你想做的吗?