python - Tkinter:对全局变量所做的更改不会保留
问题描述
每当我按下创建的按钮之一时,运行的过程最初确实会更改全局变量的值,但一旦过程完成执行,它们会出于某种原因恢复。这是代码:
from tkinter import *
transformEnabled,selectionEnabled,paintEnabled = False,False,False
root = Tk()
def hide(tool,toolkit):
for i in toolkit:
i.grid_forget()
tool=False
def toolkitFunctions(tool1,tool2,tool3,toolkit1,toolkit2,toolkit3):
print(tool1)
if tool1 == False:
print("Before other tools set to false: ",str(tool1))
if tool2:
hide(tool2,toolkit2)
if tool3:
hide(tool3,toolkit3)
for i in range(0,len(toolkit1)):
toolkit1[i].grid(row=i+4,column=0)
tool1=True
print("After other tools set: ",str(tool1))
else:
print("If tool1 already true: ",str(tool1))
hide(tool1,toolkit1)
#Transform Buttons
transformNames = ["Scale Image","Rotate Image","Move Image","Flip Image","Sharpen/Soften Image","Brightness/Constrast"]
transformButtons = [Button(root,text=transformNames[i],width=20) for i in range(0,len(transformNames))]
#SelectionButtons
selectionNames = ["Regular Shape Selection","Free hand Tool","Colour Picker"]
selectionButtons = [Button(root,text=selectionNames[i],width=20) for i in range(0,len(selectionNames))]
#Paint Buttons
paintNames = ["Paintbrush","Airbrush","Pencil","Eraser","Fill","Smudge","Dodge and Burn"]
paintButtons = [Button(root,text=paintNames[i],width=20) for i in range(0,len(paintNames))]
def transformFunctions():
toolkitFunctions(transformEnabled,selectionEnabled,paintEnabled,transformButtons,selectionButtons,paintButtons)
def selectionFunctions():
toolkitFunctions(selectionEnabled,transformEnabled,paintEnabled,selectionButtons,transformButtons,paintButtons)
def paintFunctions():
toolkitFunctions(paintEnabled,transformEnabled,selectionEnabled,paintButtons,transformButtons,selectionButtons)
transform = Button(root,text="Transform Tools",width=20,command=transformFunctions).grid(row=3,column=0)
selection = Button(root,text="Selection Tools",width=20,command=selectionFunctions).grid(row=2,column=0)
paint = Button(root,text="Paint tools",width=20,command=paintFunctions).grid(row=1,column=0)
root.mainloop()
有什么可以纠正的吗?
解决方案
您将值从全局变量发送transformEnabled
到函数,但对于 string/int/float/boolean Python 不会保留对原始变量的引用,而是将值复制到新变量。
您可以global transformEnabled
在函数中使用并直接更改transformEnabled = True
以将值分配给全局变量。但是对于这个简单的方法来说,你的复杂代码太复杂了。
在您的代码中,最好将值保存在全局字典中并发送字符串"transform"
, "selection"
,"paint"
并使用它们来访问此全局字典中的数据。
这是代码的巨大变化,但你需要它。最终,您可以尝试使用类来创建为一种功能保留按钮和值的小部件。您还可以使用Frame
对按钮进行分组并显示/隐藏此框架。
我更改了代码中的其他内容 - 基于PEP 8 -- Python 代码样式指南
import tkinter as tk
# --- functions --- (lower_case_names)
def hide(toolkit):
for item in toolkit:
item.grid_forget()
def show(toolkit):
for i, item in enumerate(toolkit):
item.grid(row=i+4, column=0) # maybe len(settings) instead of `4` so it will be works when you add more data in dictionary.
def on_click(name):
print('--- before ---')
for key, value in settings.items():
print('{} enabled: {}'.format(key, value['enabled']))
print('--- changes ---')
if not settings[name]['enabled']:
# hide other buttons
for key, value in settings.items():
print("Check:", key, key != name, value['enabled'])
if key != name and value['enabled']:
hide(value['buttons'])
value['enabled'] = False
# show buttons for `name`
print("Show:", name)
show(settings[name]['buttons'])
settings[name]['enabled'] = True
else:
# hide buttons for `name`
print("Hide:", name)
hide(settings[name]['buttons'])
settings[name]['enabled'] = False
# --- main --- (lower_case_names)
settings = {
'transform': {
'enabled': False,
'names': ["Scale Image", "Rotate Image", "Move Image", "Flip Image", "Sharpen/Soften Image", "Brightness/Constrast"],
'buttons': [],
},
'selection': {
'enabled': False,
'names': ["Regular Shape Selection", "Free hand Tool", "Colour Picker"],
'buttons': [],
},
'paint': {
'enabled': False,
'names': ["Paintbrush", "Airbrush", "Pencil", "Eraser", "Fill", "Smudge", "Dodge and Burn"],
'buttons': [],
},
}
root = tk.Tk()
settings['transform']['buttons'] = [tk.Button(root, text=item, width=20) for item in settings['transform']['names']]
# Selection Buttons
settings['selection']['buttons'] = [tk.Button(root, text=item, width=20) for item in settings['selection']['names']]
# Paint Buttons
settings['paint']['buttons'] = [tk.Button(root, text=item, width=20) for item in settings['paint']['names']]
transform = tk.Button(root, text="Transform Tools", width=20, command=lambda:on_click('transform'))
transform.grid(row=3, column=0)
selection = tk.Button(root, text="Selection Tools", width=20, command=lambda:on_click('selection'))
selection.grid(row=2, column=0)
paint = tk.Button(root, text="Paint Tools", width=20, command=lambda:on_click('paint'))
paint.grid(row=1, column=0)
root.mainloop()
编辑:相同的代码,但按钮是用循环创建的。我改用len(settings)
删除4
按钮 - 这样我可以在Help
不更改其他代码的情况下将菜单添加到字典中。
import tkinter as tk
# --- functions --- (lower_case_names)
def hide(toolkit):
for item in toolkit:
item.grid_forget()
def show(toolkit):
for i, item in enumerate(toolkit):
item.grid(row=i+len(settings), column=0)
def on_click(name):
print('--- before ---')
for key, value in settings.items():
print('{} enabled: {}'.format(key, value['enabled']))
print('--- changes ---')
if not settings[name]['enabled']:
# hide other buttons
for key, value in settings.items():
print("Check:", key, key != name, value['enabled'])
if key != name and value['enabled']:
hide(value['buttons'])
value['enabled'] = False
# show buttons for `name`
print("Show:", name)
show(settings[name]['buttons'])
settings[name]['enabled'] = True
else:
# hide buttons for `name`
print("Hide:", name)
hide(settings[name]['buttons'])
settings[name]['enabled'] = False
# --- main --- (lower_case_names)
settings = {
'transform': {
'title': "Transform Tools",
'enabled': False,
'names': ["Scale Image", "Rotate Image", "Move Image", "Flip Image", "Sharpen/Soften Image", "Brightness/Constrast"],
'buttons': [],
},
'selection': {
'title': "Selection Tools",
'enabled': False,
'names': ["Regular Shape Selection", "Free hand Tool", "Colour Picker"],
'buttons': [],
},
'paint': {
'title': "Paint Tools",
'enabled': False,
'names': ["Paintbrush", "Airbrush", "Pencil", "Eraser", "Fill", "Smudge", "Dodge and Burn"],
'buttons': [],
},
'help': {
'title': "Help",
'enabled': False,
'names': ["Help ...", "Home Page", "About"],
'buttons': [],
},
}
root = tk.Tk()
for i, name in enumerate(['paint', 'selection', 'transform', 'help']): # it could be `enumerate(settings.keys())` but sometimes it may not keep order.
settings[name]['buttons'] = [tk.Button(root, text=item, width=20) for item in settings[name]['names']]
button = tk.Button(root, text=settings[name]['title'], width=20, command=lambda arg=name:on_click(arg))
button.grid(row=i, column=0)
root.mainloop()
推荐阅读
- c++ - moveToThread vs deriving from QThread in Qt
- php - PHP发送链接以获取文件
- wordpress - 在 WordPress 网站的子页面中集成活动日历
- php - 如何将我的 htaccess 用于子目录而不是根目录?
- django - 如何预先选择 django forms.CheckboxSelectMultiple
- javascript - 为什么 console.log() 创建 /**id:4**/ 和 /**ref:4**/ 值?
- smartcard - nfc阅读器(PN532)的实际阅读速度是多少?
- reactjs - 如何在列数据网格中仅选择大于...的值
- javascript - 如何在angularjs中接收从另一个页面发送的POST数据
- python - 在 Python 中酸洗后的类继承类型检查