从笔记本中的其他选项卡访问变量
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
的文档不多。我会推荐:
- https://tkdocs.com/index.html
- 曾经有更多信息但目前无法访问的另一个网站(https://effbot.org/tkinterbook/) so you would have to go the Internet Archive Wayback Machine copy from November 2020 请查看其信息。
我们可以更加面向对象:
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()
这是你想做的吗?
大家好, 我在这个组的最后一个问题没有成功,因为我的代码太长了。 我现在已将我的代码降至最低并添加了屏幕截图。我希望这次一切都清楚而不是混乱。 我的问题是:如何检查 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
的文档不多。我会推荐:
- https://tkdocs.com/index.html
- 曾经有更多信息但目前无法访问的另一个网站(https://effbot.org/tkinterbook/) so you would have to go the Internet Archive Wayback Machine copy from November 2020 请查看其信息。
我们可以更加面向对象:
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()
这是你想做的吗?