Radiobutton - кнопка с кружочком

В tkinter с помощью виджета Radiobutton создаются радиокнопки.

Радиокнопки не создают по одной, а делают связанную группу, работающую по принципу переключателей. Когда включена одна, другие выключены.

Если мы создадим две радиокнопки без соответствующих настроек, то обе будут выключены. Нажав на одну из радиокнопок включатся все и выключить их будет невозможно:

from tkinter import *
from tkinter.ttk import *

root = Tk()

Radiobutton(text='The first').pack(anchor=W)
Radiobutton(text='The second').pack(anchor=W)
Radiobutton(text='The third').pack(anchor=W)

root.mainloop()
1
2
3
4
5
6
7
8
9
10

Результат выполнения кода:

radiobutton01

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

Связь устанавливается через общую переменную, разные значения которой соответствуют включению разных радиокнопок группы. У всех кнопок одной группы свойство variable устанавливается в одно и то же значение – связанную с группой переменную. А свойству value присваиваются разные значения этой переменной.

В tkinter нельзя использовать любую переменную для хранения состояний виджетов. Для этих целей предусмотрены специальные классы-переменные пакета tkinter:

  • BooleanVar() - класс позволяет хранить булевы значения (0 или 1 и True или False),
  • IntVar()- класс позволяет хранить целочисленные значения,
  • DoubleVar() - класс позволяет хранить дробные значения,
  • StringVar() - класс позволяет хранить строки.

Далее переменной rb_var присваивается объект типа BooleanVar. С помощью метода set() он устанавливается в значение 0:

При запуске программы включенной окажется первая радиокнопка, так как значение ее опции value совпадает с текущим значением переменной rb_var. Если кликнуть по второй радиокнопке, то она включится, а первая выключится. При этом значение rb_var станет равным 1:

from tkinter import *
from tkinter.ttk import *

root = Tk()

rb_var = BooleanVar()
rb_var.set(0)
Radiobutton(text='The first', variable=rb_var, value=0).pack(anchor=W)
Radiobutton(text='The second', variable=rb_var, value=1).pack(anchor=W)

root.mainloop()
1
2
3
4
5
6
7
8
9
10
11

Результат выполнения кода:

radiobutton02

Стоит обратить внимание на созвучие классов виджетов Button() и RadioButton(), по сути оба виджета являются кнопками и их нажатие может вызывать функцию при необходимости, т.е. можно использовать параметр command=any_function.

Рассмотрим пример вывода значения вывода выбранной кнопки:

from tkinter import *
from tkinter.ttk import *


def print_console():
    print(rb_var.get())


root = Tk()
rb_var = StringVar()
Radiobutton(text='The first', variable=rb_var, value='Clicked 1', command=print_console).pack(anchor=W)
Radiobutton(text='The second', variable=rb_var, value='Clicked 2', command=print_console).pack(anchor=W)
root.mainloop()
1
2
3
4
5
6
7
8
9
10
11
12
13

Результат вывода в консоль:

Clicked 1
Clicked 2

Упражнения

  1. Написать программу состоящую из трех радиокнопок:

    • при запуске все радиокнопки должны быть пустыми,
    • для хранения вариантов используйте переменную класса IntVar(),
    • выбор кнопок должен работать независимо.
  2. Напишите программу состоящую из метки и четырех радиокнопок. Программа отображает вопрос: "Is the capital of China?" с вариантами ответа: Beijing, Hong Kong, Tokyo, Taipei.

    • при запуске все радиокнопки должны быть пустыми,
    • для хранения вариантов используйте переменную класса StringVar(),
    • выбор кнопок должен работать независимо,
    • при нажатии радиокнопки результат выбора выводится в консоль.

    radiobutton_capitals

    Пример вывода в консоль:

    Taipei
    
    1
  3. В предыдущую программу добавьте функцию проверки выбранного результата ответа:

    • если ответ верный - Beijing, то в консоль выводится True
    • иначе False.

Проверка выбора

В программном коде обычно требуется получить данные о том, какая из кнопок включена. Делается это с помощью метода .get():

from tkinter import *
from tkinter.ttk import *

def check_answer():
    if rb_var.get() == 0:
        label_value.set('You are wrong. :(')
    elif rb_var.get() == 1:
        label_value.set('True!!!')
    elif rb_var.get() == 2:
        label_value.set('You are kidding. ;)')

root = Tk()

Label(text='How to translate: "The current window?"').pack()

rb_var = IntVar()
rb_var.set(0)
Radiobutton(text="Правильное окно", variable=rb_var, value=1).pack()
Radiobutton(text="Текущее окно", variable=rb_var, value=2).pack()
Radiobutton(text="Летящее окно", variable=rb_var, value=3).pack()
button = Button(text="Check", command=check_answer).pack()

label_value = StringVar()
label_value.set("Choose an answer!")
Label(textvariable=label_value).pack()

root.mainloop()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Результат выполнения кода:

radiobutton03

В функции change() в зависимости от считанного значения переменной label_value ход выполнения программы идет по одной из трех веток.

Также решение выбора можно реализовать вызовом отдельной функции для каждой отдельной радиокнопки, а обычная кнопка, тогда не понадобится.

Упражнения

  1. Напишите оконное приложение, в котором отображается текст: Look at the working program

    • Добавьте в приложение четыре радиокопки с соответствующим текстом: «the first», «the second», «the third», «the fourth».
    • Добавьте ещё одно поле Label, в которое выведена надпись: «… radiobutton still not choose…»
    • В каждой радиокнопке добавьте вызов функции, которая будет менять текст последнего поля, в виде: «Chosen … radiobutton». Вместо будет прописываться номер нажатой кнопки.

    radiobutton04

  2. Напишите программу, в которой имеется несколько объединенных в группу радиокнопок. Если какая-нибудь кнопка включается, то в метке должна отображаться соответствующая ей информация. Для позиционирования используйте метод grid().

    Результат может быть следующим:

    radiobutton05

  3. Напишите программу, которая проверяет правильность выбранного ответа. Добейтесь подобного расположения виджетов.

    radiobutton_06_1

    При выборе любого из вариантов выдает: "ошибка 😭"

    radiobutton_06_2

    Если выбран третий вариант "ваша версия:" и в поле ввода введено слово "правильно".

    radiobutton_06_3