Изменение значения нескольких Checkbuttons в tkinter с помощью одной функции - PullRequest
0 голосов
/ 24 ноября 2018

Я пытаюсь создать свой первый графический интерфейс с использованием tkinter для проекта, над которым я работаю на работе.У меня есть несколько пар кнопок (помеченных как «Правило» и «Трассировка» в примере ниже), которые зависят друг от друга.По умолчанию все кнопки-флажки «Правило» выбраны, а все кнопки-флажки «Трассировка» не выбраны.Если я хочу отключить определенную кнопку-правило, она должна стать красной, указывая, что она не выбрана (или выключена).И если щелкнуть снова, он должен стать зеленым, указывая, что он выбран (или включен).Я написал функцию checkbutton_state, чтобы справиться именно с этим.Ниже приведен рабочий пример того, что я пытаюсь сделать.Но моя проблема в том, что эта функция применима только для кнопки включения / выключения правила 1.Как я могу обобщить это так, чтобы я мог использовать одну и ту же функцию для всех кнопок проверки правила?

Кроме того, когда правило «Частное» отключено, соответствующая кнопка «Трассировка» должна автоматически отключаться, и пользователь не должен иметь возможность его включить.Если кнопка проверки правила включена, то соответствующая кнопка проверки должна быть отключена, но пользователь должен иметь возможность включить ее при необходимости.

Я пытался использовать метод «лямбда», чтобы попытаться обобщить функцию, но не работает.Для автоматического изменения статуса кнопки «Трассировка» я попытался использовать функцию toggle(), но она почему-то не дает желаемого результата.Я пытался найти решение этой проблемы весь день.Любые рекомендации о том, как я могу поступить с этим, были бы очень благодарны.

Моя версия Python 3.7.1 и ОС Windows 10 (64-разрядная версия).

# Import requrired libraries/packages
from tkinter import Tk, Checkbutton, IntVar

# Create intance of tkinter
root = Tk()

# Define variables
rule1_on_choice = IntVar()
rule1_trace_choice = IntVar()
rule2_on_choice = IntVar()
rule2_trace_choice = IntVar()

# Create first set of checkbutton
# The 'trace' checkbutton is dependent on the 'on' checkbutton
# If the 'on' checkbutton is turned ON, 'trace' checkbutton should be turned off but user should be able to turn it on again
# If the 'on' checkbutton is turned OFF, 'trace' checkbutton should also be turned off but user should not be able to turn it on
rule1_on_checkbutton = Checkbutton(root, text = "Rule 1 ON", indicatoron = 0, bg = "green", variable = rule1_on_choice, onvalue = 1, offvalue = 0, selectcolor = "green")
rule1_trace_checkbutton = Checkbutton(root, text = "Rule 1 Trace", indicatoron = 0, bg = "red", variable = rule1_trace_choice, onvalue = 1, offvalue = 0, selectcolor = "red")

# Create second set of checkbuttons
rule2_on_checkbutton = Checkbutton(root, text = "Rule 2 ON", indicatoron = 0, bg = "green", variable = rule2_on_choice, onvalue = 1, offvalue = 0, selectcolor = "green")
rule2_trace_checkbutton = Checkbutton(root, text = "Rule 2 Trace", indicatoron = 0, bg = "red", variable = rule2_trace_choice, onvalue = 1, offvalue = 0, selectcolor = "red")

# The 'on' checkbuttons are turned on by default
# The 'trace' checkbuttons are turned off by default
rule1_on_checkbutton.select()
rule1_trace_checkbutton.deselect()
rule2_on_checkbutton.select()
rule2_trace_checkbutton.deselect()

rule1_on_checkbutton.pack()
rule1_trace_checkbutton.pack()
rule2_on_checkbutton.pack()
rule2_trace_checkbutton.pack()

# Function to change text and color of checkbutton
# If a Rule checkbutton is clicked, should turn green whith text showing "ON"
# The same checkbutton is clicked, it should now turn red with text showing "OFF"
def checkbutton_state(event = None):

    if rule1_on_choice.get() == 1:
        rule1_on_checkbutton.configure(text = "Rule 1 OFF", bg = "red", fg = "grey")

    else:
        rule1_on_checkbutton.configure(text = "Rule 1 ON", bg = "green", fg = "white")

# Binding function to Rule 1 'on' checkbutton
rule1_on_checkbutton.bind("<Button-1>", checkbutton_state)

root.mainloop()

1 Ответ

0 голосов
/ 24 ноября 2018

Довольно сложно обобщить вашу функцию без использования lambda.Вы можете сделать что-то вроде:

def checkbutton_state(event=None):
    if rule1_on_choice.get() == 1:
        event.widget.configure(text = event.widget['text'][0:6] + " OFF", bg = "red", fg = "grey")

    else:
        event.widget.configure(text = event.widget['text'][0:6] + " ON", bg = "green", fg = "white")

# Binding function to Rule 1 'on' checkbutton
rule1_on_checkbutton.bind("<Button-1>", checkbutton_state)
rule2_on_checkbutton.bind("<Button-1>", checkbutton_state)

Если вы также хотите обобщить "rule1_on_choice", то вам нужно перейти на lambda, особенно для алгоритма, о котором вы говорите во второй части вашего вопроса,Следующий код полностью обобщает checkbutton_state:

# Using lambda
def checkbutton_state_lambda(event, rule_on_choice, text_desc):
    if rule_on_choice.get() == 1:
        event.widget.configure(text = text_desc + " OFF", bg = "red", fg = "grey")

    else:
        event.widget.configure(text = text_desc + " ON", bg = "green", fg = "white")

# Binding function to Rule 1 'on' checkbutton
rule1_on_checkbutton.bind("<Button-1>", lambda event, a=rule1_on_choice, b="Rule 1": checkbutton_state_lambda(event, a, b))
rule2_on_checkbutton.bind("<Button-1>", lambda event, a=rule2_on_choice, b="Rule 2": checkbutton_state_lambda(event, a, b))

Чтобы отключить кнопку, вы должны установить state в DISABLED.Вы можете передать в качестве аргумента кнопке «Правило» (при нажатии) кнопку «Трассировка» и соответствующим образом изменить ее состояние.

PS: Я бы лучше пошел к философии, ориентированной на класс, где у вас есть большесвобода с использованием self.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...