Tkinter: изменения, внесенные в глобальную переменную, не остаются - PullRequest
0 голосов
/ 12 марта 2020

Всякий раз, когда я нажимаю на одну из созданных кнопок, запускаемая процедура изначально изменяет значения глобальных переменных, но после завершения процедуры sh они по какой-то причине возвращаются назад. Вот код:

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()

Можно ли что-нибудь сделать, чтобы исправить это?

1 Ответ

1 голос
/ 12 марта 2020

Вы отправляете значение из глобальной переменной transformEnabled в функцию, но для строки / 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()

РЕДАКТИРОВАТЬ: Тот же код, но кнопки создаются с помощью l oop. И я использую 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...