Python / tkinter中是否有任何方法可以访问由变量名引用的子元素,但是来自其他函数?
例如,在VBA中,可以通过其名称直接引用其他窗口的元素。
例如,如果我有两个窗口,UserForm1
和UserForm2
,我可以点击Label1
上的按钮更改UserForm2
UserForm1
的文本值。
Private Sub CommandButton1_Click()
UserForm2.Label1.Caption = "Changed"
End Sub
在tkinter中,我找到winfo_children()
来访问子元素。有没有办法通过他们的名字访问它们?
请参阅下面的示例代码:
import tkinter
from tkinter import *
#----------------------------------------------------------------------
def new(parent_window):
""""""
parent_window.withdraw()
global main_window
global new_window
new_window = tkinter.Tk()
new_window.title("My App - New")
label1 = tkinter.Label(new_window, text="NEW")
label1.grid(row=0,column=0,columnspan=3,pady=10,padx=10, sticky="nsw")
b1 = tkinter.Button(new_window, text="Change It", command=lambda: showdashboard(new_window))
b1.grid(row=4,column=1,padx=20,pady=10,sticky="nwse")
b2 = tkinter.Button(new_window, text="Quit", command=lambda: quit())
b2.grid(row=5,column=1,padx=20,pady=10,sticky="nwse")
#----------------------------------------------------------------------
def dashboard(parent_window):
""""""
parent_window.withdraw()
global main_window
global dashboard_window
dashboard_window = tkinter.Tk()
dashboard_window.title("My App - Dashboard")
label1 = tkinter.Label(dashboard_window, text="Dashboard")
label1.grid(row=0,column=0,columnspan=3,pady=10,padx=10, sticky="nsw")
b1 = tkinter.Button(dashboard_window, text="New", command=lambda: new(dashboard_window))
b1.grid(row=4,column=1,padx=20,pady=10,sticky="nwse")
#----------------------------------------------------------------------
def showdashboard(parent_window):
""""""
parent_window.withdraw()
dashboard_window.update()
dashboard_window.deiconify()
#This way it works <<<<<<<<<<<<<<------!!!!!!!
byID=dashboard_window.winfo_children()
byID[0].config(text="change the value")
#But I am looking for somethin like this <<<<<<<<<<<<<<------????
dashboard_window.label1.config(text="changed the value")
#----------------------------------------------------------------------
main_window=tkinter.Tk()
main_window.title("MyApp")
label = tkinter.Label(main_window, text="My App")
label.grid(row=0,column=0,pady=10,padx=10,sticky="nwse")
b1 = tkinter.Button(main_window, text="Dashboard", command=lambda:dashboard(main_window))
b1.grid(row=1,column=0,padx=20,pady=10,sticky="nwse")
main_window.mainloop()
答案 0 :(得分:0)
我不确定名称的含义是什么:
“Python / tkinter中是否有任何方法可以访问其名称引用的子元素?”
您只需通过对象引用访问小部件:
# Procedural
import tkinter as tk
def change():
object_reference['text'] = "Changed!"
root = tk.Tk()
object_reference = tk.Label(root, text="This is a label for root-window")
object_reference.pack()
another_window = tk.Toplevel(root)
btn_in_other_window = tk.Button(another_window, text="Change")
btn_in_other_window['command'] = change
btn_in_other_window.pack()
root.mainloop()
或者如果要使用更多面向对象的方法来定义它们,则可以使用.
(点)表示法:
#oop
import tkinter as tk
class App1(tk.Toplevel):
def __init__(self, master):
super().__init__()
self.label = tk.Label(self, text="This is App1's label")
self.label.pack()
class App2(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.button = tk.Button(self, text="This is a App2's button")
self.button.pack()
def change(label):
label['text'] = "Changed!"
if __name__ == '__main__':
root = tk.Tk()
root.withdraw()
app1 = App1(root)
app2 = App2(root)
app2.button['command'] = lambda label=app1.label: change(label)
root.mainloop()
答案 1 :(得分:0)
winfo_children()
返回与小部件类型相关联的class
实例以及tkinter分配给实际tk对象的名称。
这意味着是的,我们可以参考小部件的名称,虽然我不确定除了不需要将标签分配给变量之外,这会给你带来什么好处。
from tkinter import *
root = Tk()
Label(root, text="Label1").pack()
label2 = Label(root, name="name", text="Label2")
label2.pack()
print(root.winfo_children())
print(root.nametowidget('.!label'))
print(str(label2))
Button(root, text="Delete label2", command=lambda: root.nametowidget(".name").destroy()).pack()
以上操作会导致窗口中出现两个Label
窗口小部件和一个Button
窗口小部件。第一个Label
没有存储在变量中,但我们可以很乐意在print语句中调用它。第二个存储在变量中,但您可以看到command
中的Button
我们没有引用变量,而是引用Label
的名称属性。
答案 2 :(得分:0)
不是您问题的确切答案,因为正如评论中所述
不过,可以通过以下方式获取元素窗口的子窗口小部件的列表:
root.update()
lista = list(root.children.values())
然后可以引用列表元素,并使用窗口小部件本身执行任何操作。例如,要获取第一个小部件的宽度,请执行print(lista[0].winfo_width())
。
警告:我不确定列表中的元素顺序与小部件在脚本中的显示顺序相同,尽管对我来说是按此顺序进行的。希望有人在评论中写。