Метод grid()

Grid является одним из трех менеджеров геометрии в Tkinter (другими являются уже рассмотренный ранее Pack, а также Place). У всех виджетов есть соответствующий данному менеджеру метод grid(). "Grid" с английского переводится как "сетка", однако по смыслу правильнее говорить о таблице.

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

При размещении виджетов методом grid() родительский контейнер (обычно это окно) условно разделяется на ячейки подобно таблице. Адрес каждой ячейки состоит из номера строки и номера столбца. Нумерация начинается с нуля. Ячейки можно объединять как по вертикали, так и по горизонтали.

Ячейки и их адреса

На рисунке пунктир обозначает объединение ячеек. Общая ячейка в таком случае обозначается адресом первой.

Никаких предварительных команд по разбиению родительского виджета на ячейки не выполняется. Tkinter делает это сам, исходя из указанных позиций виджетов.

Размещение виджета в той или иной ячейке задается через аргументы row и column, которым присваиваются соответственно номера строки и столбца. Чтобы объединить ячейки по горизонтали, используется атрибут columnspan, которому присваивается количество объединяемых ячеек. Опция rowspan объединяет ячейки по вертикали.

Пусть надо запрограммировать такой GUI:

Пример интерфейса

Представим данный интерфейс в виде таблицы и пронумеруем ячейки, в которых будут располагаться виджеты (подобную разбивку можно произвести в уме):

Подготовка к использованию менеджера геометрии Grid

Теперь пишем код:

from tkinter import *
root = Tk()
 
Label(text="Имя:").grid(row=0, column=0)
table_name = Entry(width=30)
table_name.grid(row=0, column=1, columnspan=3)
 
Label(text="Столбцов:").grid(row=1, column=0)
table_column = Spinbox(width=7, from_=1, to=50)
table_column.grid(row=1, column=1)
Label(text="Строк:").grid(row=1, column=2)
table_row = Spinbox(width=7, from_=1, to=100)
table_row.grid(row=1, column=3)
 
Button(text="Справка").grid(row=2, column=0)
Button(text="Вставить").grid(row=2, column=2)
Button(text="Отменить").grid(row=2, column=3)
 
root.mainloop()

Примечание. В примере используются виджеты класса Spinbox, которые не рассматривались в курсе. Spinbox похож на Entry, но для него задается список принимаемых значений, и имеется подобие скроллера.

Выполнив приведенный выше программный код, получим:

Результат размещения виджетов методом grid()

Похоже, но не совсем то, что хотелось. Теперь на помощь должны прийти другие свойства метода grid(). У него, также как у pack(), имеются атрибуты для задания внешних и внутренних отступов (padx, pady, ipadx, ipady).

Кроме этого есть атрибут sticky (липкий), который принимает значения направлений сторон света (N, S, W, E, NW, NE, SW, SE). Если, например, указать NW, то виджет прибьет к верхнему левому углу ячейки. Виджеты можно растягивать на весь объем ячейки (sticky=N+S+W+E) или только по одной из осей (N+S или W+E). Эффект от "липучки" заметен, только если виджет меньше ячейки.

from tkinter import *
root = Tk()
 
Label(text="Имя:").grid(row=0, column=0, sticky=W, pady=10, padx=10)
table_name = Entry()
table_name.grid(row=0, column=1, columnspan=3, sticky=W+E, padx=10)
 
Label(text="Столбцов:").grid(row=1, column=0, sticky=W, padx=10, pady=10)
table_column = Spinbox(width=7, from_=1, to=50)
table_column.grid(row=1, column=1, padx=10)
Label(text="Строк:").grid(row=1, column=2, sticky=E)
table_row = Spinbox(width=7, from_=1, to=100)
table_row.grid(row=1, column=3, sticky=E, padx=10)
 
Button(text="Справка").grid(row=2, column=0, pady=10, padx=10)
Button(text="Вставить").grid(row=2, column=2)
Button(text="Отменить").grid(row=2, column=3, padx=10)
 
root.mainloop()

Применение опций padx, pady и sticky метода grid()

С помощью методов grid_remove() и grid_forget() можно сделать виджет невидимым. Отличие между этими методами лишь в том, что grid_remove() запоминает прежнее положение виджета. Поэтому для его отображения в прежней ячейки достаточно применить grid() без аргументов. После grid_forget() потребуется заново конфигурировать положение виджета.

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

Практическая работа

Перепрограммируйте второе окно из практической работы предыдущего урока, используя метод grid().

Результат разметки интерфейса методом grid()

Курс с примерами решений практических работ: android-приложение, pdf-версия.

Комментарии

А как тогда указать позицию для виджета меню? Например тоже меню из след урока:
mainmenu = Menu(root) 
root.config(menu=mainmenu) 
mainmenu.grid(row=0, column=0) #вряд ли сработает...Но это не точно 

Ответ на от IVashka

Это код создания простого меню:
from tkinter import *
 
 
def function_1: pass
 
 
def function_2: pass
 
 
def function_3: pass
 
 
def function_4: pass
 
 
def function_5: pass
 
 
def function_6: pass
 
 
win = Tk()
 
menu = Menu(win)  # создаём меню
win.config(menu=menu)  # конфигурируем окно 
 
cascade1 = Menu(menu)  # создаём каскадное меню №1 в главном меню...
 
menu.add_cascade(label="Cascade 1", menu=cascade1)  # ...и добавляем в главное меню наш созданный каскад №1
 
cascade1.add_command(label="Command 1", command=function_1)  # добавляем в каскад №1 команду №1
cascade1.add_command(label="Command 2", command=function_2)  # добавляем в каскад №1 команду №2
cascade1.add_command(label="Command 3", command=function_3)  # добавляем в каскад №1 команду №3
 
cascade2 = Menu(cascade1)  # создаём каскадное меню №2 в каскаде №1
 
cascade1.add_cascade(label="Cascade 1", menu=cascade2)  # и добавляем в каскадное меню №1 наш созданный каскад №2
 
cascade2.add_command(label="Command 4", command=function_4)  # добавляем в каскад №2 команду №4
cascade2.add_command(label="Command 5", command=function_5)  # добавляем в каскад №2 команду №5
cascade2.add_command(label="Command 6", command=function_6)  # добавляем в каскад №2 команду №6
 
win.mainloop()

Два дня потел, но сделал
from tkinter import *
 
root = Tk()
root.title("FIGURE")
root.geometry('170x183')
root.grid_columnconfigure(3, minsize=50)
root.grid_columnconfigure(0, minsize=40)
 
 
 
Label(text="x1").grid(row=0, column=0, pady=10, sticky=E)
table_name = Entry(borderwidth=3, width=4)
table_name.grid(row=0, column=1,)
 
Label(text="x2").grid(row=1, column=0, pady=10, sticky=E)
table_name2 = Entry(borderwidth=3, width=4)
table_name2.grid(row=1, column=1,)
 
Label(text="y1").grid(row=0, column=3, sticky=E)
table_name1 = Entry(width=4, borderwidth=3)
table_name1.grid(row=0, column=4,)
 
Label(text="y2").grid(row=1, column=3,sticky=E)
table_name3 = Entry(width=4, borderwidth=3)
table_name3.grid(row=1, column=4,)
 
var=IntVar()
rbutton1=Radiobutton(root, text='Прямоугольник', variable=var, value=1)
rbutton2=Radiobutton(root, text='Овал', variable=var, value=2)
rbutton1.grid(row=3, column=0, columnspan=5, pady=8, padx=10, sticky=E)
rbutton2.grid(row=4, column=0, columnspan=5, padx=27,sticky=W )
Button(text="Нарисовать", width=13, borderwidth=3).grid(row=5, column=0,columnspan=5, sticky=E, padx=15 )
 
root.mainloop()

Я пока не очень разобрался в grid'e, но смог придумать неплохую, как по мне идею. У меня не получалось пропускать клетки, чтобы сделать отступы между Entry от x1 и Label y1. Поэтому я оставлял Label с белым текстом, там, где мне нужен пропуск. Размер пропуска можно регулировать размер текста Label'a. Хочу узнать, как это правильно. Заранее спасибо. Вот этот код:
from tkinter import *
 
root = Tk()
 
Label(text='x', fg='white').grid(row=0, column=0, pady=10, sticky=W)
 
Label(text='x1').grid(row=0, column=1, pady=10, sticky=E)
e1 = Entry(width=4)
e1.grid(row=0, column=2, sticky=W)
 
Label(text='x', fg='white').grid(row=0, column=3, pady=10)
 
Label(text='y1').grid(row=0, column=4, pady=10, sticky=W)
e1 = Entry(width=4)
e1.grid(row=0, column=5, sticky=E)
 
Label(text='x', fg='white').grid(row=1, column=6, pady=10, sticky=E)
 
Label(text='x', fg='white').grid(row=1, column=0, pady=10, sticky=W)
 
Label(text='x2').grid(row=1, column=1, pady=10, sticky=E)
e1 = Entry(width=4)
e1.grid(row=1, column=2, sticky=W)
 
Label(text='x', fg='white').grid(row=1, column=3, pady=10)
 
Label(text='y2').grid(row=1, column=4, pady=10, sticky=W)
e1 = Entry(width=4)
e1.grid(row=1, column=5, sticky=E)
 
Label(text='x', fg='white').grid(row=1, column=6, pady=10, sticky=E)
 
r = BooleanVar()
r.set(0)
 
r1 = Radiobutton(value=0, variable=r, text='Rectangle')
r2 = Radiobutton(value=1, variable=r, text='Oval')
 
r1.grid(row=2, column=1, columnspan=3, sticky=W, pady=5)
r2.grid(row=3, column=1, columnspan=3, sticky=W)
 
Button(text='Draw figure').grid(row=4, column=1, columnspan=3, pady=10)
 
root.mainloop()

Ответ на от fsociety

Идея с белым текстом просто прекрасная, но также можно заменить текст на пробелы, чтобы не сбивать с толку читающего код и чтобы убрать fg='white' вот так:
Label(text=' ').grid(row=0, column=0)  # white text
Label(text=' ').grid(row=0, column=3)  # white text
Label(text=' ').grid(row=0, column=3)  # white text
Label(text=' ').grid(row=1, column=6)  # white text
Label(text=' ').grid(row=1, column=0)  # white text
Label(text=' ').grid(row=1, column=3)  # white text
Label(text=' ').grid(row=1, column=6)  # white text
<python>
 
Стоит структурировать код, чтобы не было досадных ошибок, как в вашем коде:
 
<python>
......
e1 = Entry(width=4)
e1.grid(row=0, column=2, sticky=W)
......
e1 = Entry(width=4)
e1.grid(row=0, column=5, sticky=E)
......
e1 = Entry(width=4)
e1.grid(row=1, column=2, sticky=W)
......
e1 = Entry(width=4)
e1.grid(row=1, column=5, sticky=E)
......
Одним именем называть разные виджеты Entry не стоит, а из-за беспорядка в коде эти ошибки незаметны. Вот так примерно выглядит структурированный вариант Вашего кода:
from tkinter import *
 
root = Tk()
root.title('Drawer')
 
button_draw = Button(text='Draw figure')
 
e1 = Entry(width=4)
e2 = Entry(width=4)
e3 = Entry(width=4)
e4 = Entry(width=4)
 
radiobutton_var = BooleanVar()
radiobutton_var.set(0)
r1 = Radiobutton(value=0, variable=radiobutton_var, text='Rectangle')
r2 = Radiobutton(value=1, variable=radiobutton_var, text='Oval')
 
 
button_draw.grid(row=4, column=1, columnspan=6)
r1.grid(row=2, column=1, columnspan=3, sticky=W)
r2.grid(row=3, column=1, columnspan=3, sticky=W)
e1.grid(row=0, column=2)
e2.grid(row=0, column=5)
e3.grid(row=1, column=2)
e4.grid(row=1, column=5)
 
 
Label(text='y1').grid(row=0, column=4)
Label(text='x1').grid(row=0, column=1)
Label(text='x2').grid(row=1, column=1)
Label(text='y2').grid(row=1, column=4)
 
''''''
Label(text='x', fg='white').grid(row=0, column=0)  # white text
Label(text='x', fg='white').grid(row=0, column=3)  # white text
Label(text='x', fg='white').grid(row=0, column=3)  # white text
Label(text='x', fg='white').grid(row=1, column=6)  # white text
Label(text='x', fg='white').grid(row=1, column=0)  # white text
Label(text='x', fg='white').grid(row=1, column=3)  # white text
Label(text='x', fg='white').grid(row=1, column=6)  # white text
''''''
 
root.mainloop()

Делал пару недель, но вот:
try:
    try:
        try:
            from tkinter import *
            from tkinter.messagebox import *
            from time import *
            from random import *
            import sys
        except ModuleNotFoundError:
            sys.exit()
 
 
        def second_men():
            global second_menu
            second_menu.add_command(label='White', command=whit)
            second_menu.add_command(label='Grey', command=gre)
            second_menu.add_command(label='Black', command=bla)
            second_menu.add_separator()
            second_menu.add_command(label='Red', command=re)
            second_menu.add_command(label='Orange', command=ora)
            second_menu.add_command(label='Yellow', command=ye)
            second_menu.add_command(label='Green', command=gr)
            second_menu.add_command(label='Sky Blue', command=sb)
            second_menu.add_command(label='Blue', command=bl)
            second_menu.add_command(label='Purple', command=pp)
            second_menu.add_separator()
            second_menu.add_command(label='Pink', command=pi)
            second_menu.add_command(label='Brown', command=br)
            second_menu.add_command(label='Magenta', command=mg)
            second_menu.add_command(label='Olive', command=ov)
            second_menu.add_command(label='Cyan', command=cy)
            second_menu.add_command(label='Green + Yellow', command=gy)
            second_menu.add_command(label='Lawn Green', command=lg)
 
 
        def count(key):
            global entry
            if key in '0123456789+-*/.()':
                entry.insert(END, key)
            elif key == '√':
                entry.insert(END, '**(0.5)')
            elif key == 'x²':
                entry.insert(END, '**2')
            elif key == 'x³':
                entry.insert(END, '**3')
            elif key == 'C':
                entry.delete(0, END)
            elif key == '←':
                entry.delete(len(entry.get()) - 1)
            elif key == '=':
                try:
                    rez = eval(entry.get())
                    entry.delete(0, END)
                    entry.insert(END, str(rez))
                except SyntaxError:
                    showerror('Error', 'The expression wrong')
                except ZeroDivisionError:
                    showerror('Error', 'The expression wrong')
                except NameError:
                    showerror('Error', 'The expression wrong')
 
 
        def about():
            showinfo('Info', 'this program was written '
                             'on 18.07.2019')
 
 
        def exi():
            win.destroy()
 
 
        def setting():
            root2 = Tk()
            root2.title("Settings")
            root2.geometry("180x100+600+100")
            root2.resizable(width=False, height=False)
            Label(root2, text="Themes").pack()
            t = IntVar()
            r1 = Radiobutton(root2, text="Classic", variable=t, value=1, command=classic_calc)
            r1.pack()
            r1.select()
            r2 = Radiobutton(root2, text="Dark", variable=t, value=2, command=dark_calc)
            r2.pack()
 
 
        def draw():
            canvas.delete("all")
            x1 = entry1.get()
            x2 = entry2.get()
            y1 = entry3.get()
            y2 = entry4.get()
            f = entry5.get()
            w = entry7.get()
            o = entry6.get()
            if w == '':
                w = '2'
            if x1 == '':
                x1 = '10'
            if x2 == '':
                x2 = '60'
            if y1 == '':
                y1 = '10'
            if y2 == '':
                y2 = '60'
 
            if f == 'w' or f == '':
                f = 'white'
            if f == 'r':
                f = 'red'
            if f == 'o':
                f = 'orange'
            if f == 'y':
                f = 'yellow'
            if f == 'sb':
                f = 'skyblue'
            if f == 'b':
                f = 'blue'
            if f == 'g':
                f = 'green'
            if f == 'p':
                f = 'purple'
            if o == 'b' or o == '':
                o = 'black'
            if o == 'r':
                o = 'red'
            if o == 'o':
                o = 'orange'
            if o == 'y':
                o = 'yellow'
            if o == 'sb':
                o = 'skyblue'
            if o == 'b':
                o = 'blue'
            if o == 'g':
                o = 'green'
            if o == 'p':
                o = 'purple'
 
            try:
                y1 = int(y1)
                x2 = int(x2)
                y2 = int(y2)
                w = int(w)
                x1 = int(x1)
                if w > 10:
                    w = 10
                if (x1 < 0) or (x1 > wh) or \
                        (x2 < 0) or (x2 > wh) or \
                        (y1 < 0) or (y1 > wh) or \
                        (y2 < 0) or (y2 > wh) or \
                        (w < 0):
                    showerror("ValueError",
                              "Что-то пошло не так...")
                else:
                    try:
                        if r.get() == 1:
                            canvas.create_rectangle(x1, y1, x2, y2,
                                                    fill=f, outline=o,
                                                    width=w)
                        else:
                            canvas.create_oval(x1, y1, x2, y2,
                                               fill=f, outline=o,
                                               width=w)
                    except TclError:
                        showerror("Error",
                                  "Что-то пошло не так...")
            except ValueError:
                showerror("Error",
                          "Что-то пошло не так...")
 
 
        def calc():
            global win, win2, entry
            try:
                win.destroy()
                win2.destroy()
            except TclError:
                pass
            win = Tk()
            win.title("Calc")
            win.resizable(width=False, height=False)
            m = Menu(win)
            win.config(menu=m)
            item1 = Menu(m, tearoff=0)
            m.add_cascade(label="File", menu=item1)
            item1.add_command(label="About", command=about)
            item1.add_command(label="Settings", command=setting)
            item1.add_command(label="Update", command=calc)
            item1.add_separator()
            item1.add_command(label="Open Drawer", command=update)
            entry = Entry(width="60", bd=3, relief=SUNKEN)
            entry.grid(row=0, columnspan=8)
            classic_calc()
            win.mainloop()
 
 
        def update():
            global canvas, win, win2, label, label1, label2, \
                label3, label4, label5, label6, label7, \
                entry1, entry2, entry3, entry4, \
                entry5, entry6, entry7, radio1, radio2, \
                btn1, main_menu, null_menu, \
                null_1_menu, first_menu, second_menu, r, wh
            try:
                win.destroy()
                win2.destroy()
            except TclError:
                pass
            win = Tk()
            win.title('Panel')
            win.geometry("165x220+343+250")
            win.resizable(width=False, height=False)
            r = IntVar()
            wh = 500
 
            label = Label(text='Coordinate system')
            label1 = Label(text="x1")
            label2 = Label(text="x2")
            label3 = Label(text="y1")
            label4 = Label(text="y2")
            label5 = Label(text="fill")
            label6 = Label(text="outline")
            label7 = Label(text="width")
 
            entry1 = Entry(width=8)
            entry2 = Entry(width=8)
            entry3 = Entry(width=8)
            entry4 = Entry(width=8)
            entry5 = Entry(width=18)
            entry6 = Entry(width=18)
            entry7 = Entry(width=18)
 
            radio1 = Radiobutton(text="rectangle",
                                 variable=r, value=1,
                                 command=fun1)
            radio2 = Radiobutton(text="oval", variable=r,
                                 value=2, command=fun2)
 
            btn1 = Button(text="DRAW!", command=draw)
 
            label.grid(row=0, columnspan=4)
            label1.grid(row=1, column=0, sticky=E)
            label2.grid(row=2, column=0, sticky=E)
            label3.grid(row=1, column=2, sticky=E)
            label4.grid(row=2, column=2, sticky=E)
            label5.grid(row=3, sticky=W)
            label6.grid(row=4, sticky=W)
            label7.grid(row=5, sticky=W)
 
            entry1.grid(row=1, column=1, sticky=W)
            entry2.grid(row=2, column=1, sticky=W)
            entry3.grid(row=1, column=3, sticky=W)
            entry4.grid(row=2, column=3, sticky=W)
            entry5.grid(row=3, column=1, columnspan=3, sticky=W)
            entry6.grid(row=4, column=1, columnspan=3, sticky=W)
            entry7.grid(row=5, column=1, columnspan=3, sticky=W)
 
            radio1.grid(row=6, columnspan=4, sticky=W)
            radio2.grid(row=7, columnspan=4, sticky=W)
            radio1.select()
            btn1.grid(row=8, columnspan=4)
            main_menu = Menu(win)
            win.config(menu=main_menu)
            null_menu = Menu(main_menu, tearoff=0)
            main_menu.add_cascade(label='File', menu=null_menu)
            null_1_menu = Menu(main_menu, tearoff=0)
            null_menu.add_cascade(label='About', menu=null_1_menu)
            null_1_menu.add_command(label='Coordinate system', command=info_c)
            null_1_menu.add_command(label='Fill', command=info_fill)
            null_1_menu.add_command(label='Outline', command=info_out)
            null_1_menu.add_command(label='Width', command=info_wid)
            null_1_menu.add_command(label='Rectangle / Oval',
                                    command=info_ro)
            null_menu.add_command(label='Info',
                                  command=info)
            null_menu.add_separator()
            null_menu.add_command(label='Exit',
                                  command=ex)
            null_menu.add_command(label='Update',
                                  command=update)
            null_menu.add_separator()
            null_menu.add_command(label='Open Calculator',
                                  command=calc)
            first_menu = Menu(main_menu, tearoff=0)
            main_menu.add_cascade(label='Theme', menu=first_menu)
            first_menu.add_command(label='Classic', command=classic)
            first_menu.add_command(label='Dark', command=dark)
            first_menu.add_command(label='Color theme', command=color)
            second_menu = Menu(main_menu, tearoff=0)
            main_menu.add_cascade(label='Background of canvas', menu=second_menu)
            second_men()
            win2 = Tk()
            win2.title("rectangle")
            win2.geometry("500x500+524+250")
            win2.resizable(width=False, height=False)
            canvas = Canvas(win2, width=wh, height=wh)
            classic()
            canvas.pack()
            win.mainloop()
            win2.mainloop()
 
 
        def dark_calc():
            global win
            win.config(bg='black')
            buttons_all = ["7", "8", "9", "0", "+", "-", "*", "/",
                           "4", "5", "6", "x" + "²", "x³", "√", "(", ")",
                           "1", "2", "3", ".", "←", "C", "=", " "]
            q = 0
            w = 1
            for i in buttons_all:
                btn = Button(win, text=i, width=8, bd=4, bg='dimgrey', fg='white', command=lambda x=i: count(x))
                btn.grid(row=w, column=q, padx=1, pady=1)
                q += 1
                if q > 7:
                    q = 0
                    w += 1
 
 
        def classic_calc():
            global win
            win.config(bg='white')
            buttons_all = ["7", "8", "9", "0", "+", "-", "*", "/",
                           "4", "5", "6", "x" + "²", "x³", "√", "(", ")",
                           "1", "2", "3", ".", "←", "C", "=", " "]
            q = 0
            w = 1
            for i in buttons_all:
                btn = Button(win, text=i, width=8, bd=4, bg='lightgrey', fg='black', command=lambda x=i: count(x))
                btn.grid(row=w, column=q, padx=1, pady=1)
                q += 1
                if q > 7:
                    q = 0
                    w += 1
 
 
        def classic():
            global canvas, win, label, label1, label2, \
                label3, label4, label5, label6, label7, \
                entry1, entry2, entry3, entry4, \
                entry5, entry6, entry7, radio1, radio2, \
                btn1
            canvas.configure(bg="white")
            win.config(bg="white")
            label.config(bg="white")
            label1.config(bg="white")
            label2.config(bg="white")
            label3.config(bg="white")
            label4.config(bg="white")
            label5.config(bg="white")
            label6.config(bg="white")
            label7.config(bg="white")
            entry1.config(bg="white")
            entry2.config(bg="white")
            entry3.config(bg="white")
            entry4.config(bg="white")
            entry5.config(bg="white")
            entry6.config(bg="white")
            entry7.config(bg="white")
            radio1.config(bg="white")
            radio2.config(bg="white")
            btn1.config(bg="white")
            # ------------------- #
            label.config(fg="black")
            label1.config(fg="black")
            label2.config(fg="black")
            label3.config(fg="black")
            label4.config(fg="black")
            label5.config(fg="black")
            label6.config(fg="black")
            label7.config(fg="black")
            entry1.config(fg="black")
            entry2.config(fg="black")
            entry3.config(fg="black")
            entry4.config(fg="black")
            entry5.config(fg="black")
            entry6.config(fg="black")
            entry7.config(fg="black")
            radio1.config(fg="black")
            radio2.config(fg="black")
            btn1.config(fg="black")
 
 
        def dark():
            global canvas, win, label, label1, label2, \
                label3, label4, label5, label6, label7, \
                entry1, entry2, entry3, entry4, \
                entry5, entry6, entry7, radio1, radio2, \
                btn1
            canvas.configure(bg="black")
            win.config(bg="black")
            label.config(bg="black")
            label1.config(bg="black")
            label2.config(bg="black")
            label3.config(bg="black")
            label4.config(bg="black")
            label5.config(bg="black")
            label6.config(bg="black")
            label7.config(bg="black")
            entry1.config(bg="silver")
            entry2.config(bg="silver")
            entry3.config(bg="silver")
            entry4.config(bg="silver")
            entry5.config(bg="silver")
            entry6.config(bg="silver")
            entry7.config(bg="silver")
            radio1.config(bg="black")
            radio2.config(bg="black")
            btn1.config(bg="silver")
            # ------------------- #
            label.config(fg="white")
            label1.config(fg="white")
            label2.config(fg="white")
            label3.config(fg="white")
            label4.config(fg="white")
            label5.config(fg="white")
            label6.config(fg="white")
            label7.config(fg="white")
            entry1.config(fg="black")
            entry2.config(fg="black")
            entry3.config(fg="black")
            entry4.config(fg="black")
            entry5.config(fg="black")
            entry6.config(fg="black")
            entry7.config(fg="black")
            radio1.config(fg="white")
            radio2.config(fg="white")
            btn1.config(fg="black")
 
 
        def color():
            global canvas, win, label, label1, label2, \
                label3, label4, label5, label6, label7, \
                entry1, entry2, entry3, entry4, \
                entry5, entry6, entry7, radio1, radio2, \
                btn1
            canvas.configure(bg="orange")
            win.config(bg="yellow")
            label.config(bg="orange")
            label1.config(bg="green")
            label2.config(bg="skyblue")
            label3.config(bg="lawngreen")
            label4.config(bg="blue")
            label5.config(bg="red")
            label6.config(bg="magenta")
            label7.config(bg="black")
            entry1.config(bg="olive")
            entry2.config(bg="grey")
            entry3.config(bg="red")
            entry4.config(bg="green")
            entry5.config(bg="magenta")
            entry6.config(bg="lawngreen")
            entry7.config(bg="grey")
            radio1.config(bg="red")
            radio2.config(bg="lawngreen")
            btn1.config(bg="orange")
            # ------------------- #
            label.config(fg="white")
            label1.config(fg="white")
            label2.config(fg="white")
            label3.config(fg="white")
            label4.config(fg="white")
            label5.config(fg="white")
            label6.config(fg="white")
            label7.config(fg="white")
            entry1.config(fg="white")
            entry2.config(fg="white")
            entry3.config(fg="white")
            entry4.config(fg="white")
            entry5.config(fg="white")
            entry6.config(fg="white")
            entry7.config(fg="white")
            radio1.config(fg="white")
            radio2.config(fg="white")
            btn1.config(fg="white")
 
 
        def info():
            showinfo('Info', 'this program was written '
                             'on 19.07.2019')
 
 
        def info_c():
            showinfo('Info', 'x1 - first x coordinate; '
                             'y1 - first y coordinate; '
                             'x2 - second x coordinate; '
                             'y2 - second y coordinate')
 
 
        def info_fill():
            showinfo('Info', 'This item is '
                             'responsible for filling the shape')
            showinfo('Info', 'the list of colors '
                             'can be taken from here: '
                             'http://gg.gg/ekeiy')
 
 
        def info_out():
            showinfo('Info', 'This item is '
                             'responsible for filling the outline')
            showinfo('Info', 'the list of colors '
                             'can be taken from here: '
                             'http://gg.gg/ekeiy')
 
 
        def info_wid():
            showinfo('Info', 'This item is responsible '
                             'for the thickness of the border shape')
 
 
        def info_ro():
            showinfo('Info', 'The buttons in this section '
                             'are responsible for the shape '
                             'that will be drawn on the canvas')
 
 
        # BG OF CANVAS #
 
 
        def whit():
            global canvas
            canvas.configure(bg="white")
 
 
        def gre():
            global canvas
            canvas.configure(bg="grey")
 
 
        def bla():
            global canvas
            canvas.configure(bg="black")
 
 
        def re():
            global canvas
            canvas.configure(bg="red")
 
 
        def gr():
            global canvas
            canvas.configure(bg="green")
 
 
        def sb():
            global canvas
            canvas.configure(bg="skyblue")
 
 
        def bl():
            global canvas
            canvas.configure(bg="blue")
 
 
        def ye():
            global canvas
            canvas.configure(bg="yellow")
 
 
        def ora():
            global canvas
            canvas.configure(bg="orange")
 
 
        def pp():
            global canvas
            canvas.configure(bg="purple")
 
 
        def pi():
            global canvas
            canvas.configure(bg="pink")
 
 
        def br():
            global canvas
            canvas.configure(bg="brown")
 
 
        def mg():
            global canvas
            canvas.configure(bg="magenta")
 
 
        def ov():
            global canvas
            canvas.configure(bg="olive")
 
 
        def cy():
            global canvas
            canvas.configure(bg="cyan")
 
 
        def gy():
            global canvas
            canvas.configure(bg="greenyellow")
 
 
        def lg():
            global canvas
            canvas.configure(bg="lawngreen")
 
 
        def ex():
            win.destroy()
            win2.destroy()
 
 
        def fun1():
            win2.title("Rectangle")
 
 
        def fun2():
            win2.title("Oval")
 
 
        # --------------------------------------------- #
        # ------------- Capital Program --------------- #
        # --------------------------------------------- #
 
        win = Tk()
        win.title('Panel')
        win.geometry("165x220+343+250")
        win.resizable(width=False, height=False)
        r = IntVar()
        wh = 500
 
        label = Label(text='Coordinate system')
        label1 = Label(text="x1")
        label2 = Label(text="x2")
        label3 = Label(text="y1")
        label4 = Label(text="y2")
        label5 = Label(text="fill")
        label6 = Label(text="outline")
        label7 = Label(text="width")
 
        entry1 = Entry(width=8)
        entry2 = Entry(width=8)
        entry3 = Entry(width=8)
        entry4 = Entry(width=8)
        entry5 = Entry(width=18)
        entry6 = Entry(width=18)
        entry7 = Entry(width=18)
 
        radio1 = Radiobutton(text="rectangle",
                             variable=r, value=1,
                             command=fun1)
        radio2 = Radiobutton(text="oval", variable=r,
                             value=2, command=fun2)
 
        btn1 = Button(text="DRAW!", command=draw)
 
        label.grid(row=0, columnspan=4)
        label1.grid(row=1, column=0, sticky=E)
        label2.grid(row=2, column=0, sticky=E)
        label3.grid(row=1, column=2, sticky=E)
        label4.grid(row=2, column=2, sticky=E)
        label5.grid(row=3, sticky=W)
        label6.grid(row=4, sticky=W)
        label7.grid(row=5, sticky=W)
 
        entry1.grid(row=1, column=1, sticky=W)
        entry2.grid(row=2, column=1, sticky=W)
        entry3.grid(row=1, column=3, sticky=W)
        entry4.grid(row=2, column=3, sticky=W)
        entry5.grid(row=3, column=1, columnspan=3, sticky=W)
        entry6.grid(row=4, column=1, columnspan=3, sticky=W)
        entry7.grid(row=5, column=1, columnspan=3, sticky=W)
 
        radio1.grid(row=6, columnspan=4, sticky=W)
        radio2.grid(row=7, columnspan=4, sticky=W)
        radio1.select()
        btn1.grid(row=8, columnspan=4)
        main_menu = Menu(win)
        win.config(menu=main_menu)
        null_menu = Menu(main_menu, tearoff=0)
        main_menu.add_cascade(label='File', menu=null_menu)
        null_1_menu = Menu(main_menu, tearoff=0)
        null_menu.add_cascade(label='About', menu=null_1_menu)
        null_1_menu.add_command(label='Coordinate system', command=info_c)
        null_1_menu.add_command(label='Fill', command=info_fill)
        null_1_menu.add_command(label='Outline', command=info_out)
        null_1_menu.add_command(label='Width', command=info_wid)
        null_1_menu.add_command(label='Rectangle / Oval',
                                command=info_ro)
        null_menu.add_command(label='Info',
                              command=info)
        null_menu.add_separator()
        null_menu.add_command(label='Exit',
                              command=ex)
        null_menu.add_command(label='Update',
                              command=update)
        null_menu.add_separator()
        null_menu.add_command(label='Open Calculator',
                              command=calc)
        first_menu = Menu(main_menu, tearoff=0)
        main_menu.add_cascade(label='Theme', menu=first_menu)
        first_menu.add_command(label='Classic', command=classic)
        first_menu.add_command(label='Dark', command=dark)
        first_menu.add_command(label='Color theme', command=color)
        second_menu = Menu(main_menu, tearoff=0)
        main_menu.add_cascade(label='Background of canvas', menu=second_menu)
        second_men()
        win2 = Tk()
        win2.title("rectangle")
        win2.geometry("500x500+524+250")
        win2.resizable(width=False, height=False)
        canvas = Canvas(win2, width=wh, height=wh)
        classic()
        canvas.pack()
        win.mainloop()
        win2.mainloop()
    except TclError:
        pass
except SyntaxError:
    pass
except NameError:
    pass