Создайте свое первое графическое приложение на Python: начало работы с Tkinter
Перейти по ссылкам
- Что мы создаем
- Настройка Tkinter
- Создание главного окна
- Добавление необходимых виджетов
- Обработка событий
- Работа над пользовательским интерфейсом
- Некоторая окончательная полировка
Создание программных проектов — это здорово. Но а если у них есть графический интерфейс? Еще лучше! Создание GUI-приложения имеет множество преимуществ. В итоге вы получаете что-то, что оценят даже друзья, далекие от технологий. Вот почему мы собираемся создать GUI-приложение на Python и при этом изучить библиотеку Tkinter.
Что мы создаем
Для этого учебного пособия я решил сделать приложение для списка дел. Это классический проект, который не слишком сложен и, в то же время, позволяет изучить множество программных концепций. Более того, если вам понравится конечный результат, вы сможете использовать его и для себя.
Существует консольная версия приложения списка дел на Python. Оно охватывает многие основы, которые полезно знать. Поэтому я бы порекомендовал вам сначала ознакомиться с ним, так как это поможет вам лучше понять это руководство. Однако это не абсолютно необходимо, потому что я проведу вас по коду и объясню, что происходит, чтобы вы понимали происходящее без особых предварительных знаний.
Я бы также порекомендовал вам освежить знания по основам Python на случай, если вы не знаете этот язык. Без этого вам будет трудно следовать этому руководству.
Настройка Tkinter
Хорошая вещь в Tkinter заключается в том, что он идет в комплекте с вашей установкой Python. Так что нет необходимости что-либо устанавливать. Давайте проверим это, импортировав модуль tkinter и проверив его версию.
import tkinter as tk print(tk.TkVersion)
Вам следует получить номер версии на вашей консоли. У меня это 8.6. Если вы получите ошибку, это значит, что в вашей установке Python этого может не быть. Возможно, вам потребуется переустановить Python или, если вы используете Linux, установить правильный пакет для tkinter в соответствии с вашей дистрибуцией.
Создание главного окна
Если это сработало для вас, давайте теперь создадим главное окно. Мы настроим окно с подходящим размером и заголовком.
import tkinter as tk # Create the main application window root = tk.Tk() root.title("To-Do List App") root.geometry("400x500") # Prevent window from being resized root.resizable(False, False) # Start the event loop root.mainloop()
Что мы сделали?
- Мы импортируем Tkinter и задаем ему псевдоним
tkдля удобства. root=tk.Tk()создаёт главное окно приложения- Мы устанавливаем заголовок окна с помощью
root.title() root.geometry("400x500")задаёт размер окнаroot.resizable(False, False)предотвращает возможность изменения размера окна пользователем. Первый параметр управляет горизонтальным изменением размера, второй — вертикальным.- Наконец,
root.mainloop()запускает главный цикл событий. Это очень важно! Без него ваше окно появилось бы и сразу же закрылось.
Когда вы запустите этот код, вы увидите пустое окно с названием «Приложение Список Дел». Пока оно пустое, но на следующем этапе мы начнем заполнять его виджетами.
Добавление необходимых виджетов
Приложению для списка дел нужно много виджетов: поле для ввода, кнопки для управления задачами и поле для их просмотра. Давайте начнем их добавлять. Напишите эти строки после строки root.resizable(False, False).
task_entry = tk.Entry(root, width=35, font=("Arial", 12)) task_entry.pack(pady=10)
Мы создаем виджет Entry для ввода однострочного текста. Мы задаем ему ширину, шрифт и немного вертикального отступа. Затем мы добавляем кнопку.
add_button = tk.Button(root, text="Add Task", width=20, font=("Arial", 10)) add_button.pack(pady=5)
Снова мы задаём ему ширину, шрифт, немного вертикальных отступов и текстовую метку. Эта кнопка будет использоваться для добавления задач. После этого мы создаём список для отображения задач.
task_listbox = tk.Listbox(root, width=50, height=15, font=("Arial", 10)) task_listbox.pack(pady=10)
Как и в случае с предыдущими виджетами, мы задаём ему некоторые свойства, включая высоту. Мы используем менеджер геометрии pack(), чтобы располагать виджеты в порядке их добавления. Tkinter также предлагает grid() для более точного управления. В этом уроке мы будем использовать pack(), так как он проще для начинающих.
Когда вы запустите этот код, вы увидите пустое текстовое поле вверху, кнопку «Добавить задачу» под ним и большой пустой список внизу.
Теперь это больше похоже на приложение для дел.
Обработка событий
В данный момент наше приложение имеет только пользовательский интерфейс. Функциональности нет. Давайте сделаем наше приложение интерактивным. Мы собираемся создать функцию для добавления задач в список. Добавьте этот фрагмент кода после строки root.resizable(False, False).
def add_task(): task = task_entry.get() if task: task_listbox.insert(tk.END, task) task_entry.delete(0, tk.END) else: print("Please enter a task!")
Сначала мы получаем текст из поля ввода. Затем мы проверяем, пустое ли поле или нет, с помощью условия. Если оно не пустое, мы вставляем текст, который является задачей, в список и очищаем поле ввода. В противном случае мы выводим простое сообщение в консоль о том, что задача не введена. Следующее, что нужно сделать, это связать это с кнопкой.
add_button = tk.Button(root, text="Add Task", width=20, font=("Arial", 10), command=add_task)
Мы передаем новый аргумент — функцию add_task(). Это указывает кнопке вызвать функцию при нажатии. Обратите внимание, что мы не ставим скобки при передаче аргумента.
Давайте попробуем это. Напишите что-нибудь в поле ввода и нажмите кнопку «Добавить задачу», чтобы проверить, добавляется ли задача или нет. Затем попробуйте добавить задачу, когда поле ввода пустое.
Отлично. Всё работает как ожидалось. Теперь вы можете добавлять задачи.
Работа над пользовательским интерфейсом
Давайте добавим больше функциональности, чтобы наше приложение списка дел стало действительно полезным. Мы добавим возможность удалять задачи, очищать все задачи и отмечать задачи как выполненные. Давайте добавим функцию для удаления задачи. Добавьте этот код после функции add_task().
def delete_task(): try: selected_index = task_listbox.curselection()[0] task_listbox.delete(selected_index) except IndexError: print("Please select a task to delete!")
Здесь curselection()[0] получает первый (и единственный) выбранный элемент из кортежа индексов выбранных элементов. Затем мы удаляем элемент по этому индексу. Мы также используем try/except для более надежной обработки ошибок. После этого давайте добавим функцию для очистки всех задач в списке.
def clear_all_tasks(): task_listbox.delete(0, tk.END)
Эта функция удаляет все задачи с начала до конца. Теперь добавим функцию, которая будет отмечать задачу как выполненную.
def mark_complete(): try: selected_index = task_listbox.curselection()[0] task = task_listbox.get(selected_index) # Check if task is already marked complete if not task.startswith("✓ "): # Mark as complete with checkmark task_listbox.delete(selected_index) task_listbox.insert(selected_index, "✓ " + task) task_listbox.itemconfig(selected_index, fg="gray") except IndexError: print("Please select a task to mark as complete!")
Здесь происходит многое. Сначала мы получаем выбранное задание, так же, как мы делали ранее для удаления. Затем мы используем условные выражения, чтобы проверить, соответствует ли текст задания определённому требованию. А именно, если он начинается с галочки ✓, за которой следует пробел.
Если нет, значит задача не выполнена. Мы удаляем задачу из списка и вставляем её снова с галочкой и пробелом. Для наглядности мы также делаем её текст серым. Если задача не выбрана, выводим полезное сообщение. Так как нет прямой возможности редактирования, мы сначала удаляем задачу и вставляем её снова на то же место с отметкой.
Нам всё ещё нужно привязать эти функции к некоторым кнопкам. Сначала давайте создадим рамку, где мы разместим новые кнопки. Добавьте это прямо перед root.mainloop().
button_frame = tk.Frame(root) button_frame.pack(pady=10)
Frame — это контейнерный виджет, который группирует другие виджеты вместе. Внутри этого фрейма мы размещаем три новые кнопки: кнопку удаления, кнопку очистки и кнопку «отметить как выполнено».
mark_button = tk.Button(button_frame, text="Mark Complete", width=15, font=("Arial", 10), command=mark_complete) mark_button.grid(row=0, column=0, padx=5) delete_button = tk.Button(button_frame, text="Delete Task", width=15, font=("Arial", 10), command=delete_task) delete_button.grid(row=0, column=1, padx=5) clear_button = tk.Button(button_frame, text="Clear All", width=15, font=("Arial", 10), command=clear_all_tasks) clear_button.grid(row=0, column=2, padx=5)
В отличие от предыдущего раза, здесь мы использовали grid(). Это позволяет нам точно выравнивать кнопки по горизонтали. Параметры row и column определяют, где мы хотим разместить конкретный виджет в сеточной компоновке. Мы также добавляем некоторый горизонтальный отступ к каждой кнопке и её соответствующему функционалу.
Теперь наше приложение работает как настоящее приложение для дел.
Некоторая окончательная полировка
Приложение работает хорошо. Но оно выглядит немного скучно. Давайте сделаем его красивее, чтобы оно выглядело более профессионально. Добавьте эту строку после строки root.resizable(False, False).
root.config(bg="#f0f0f0") # Light gray background
Он устанавливает приятный светло-серый фон для всего окна. Далее создадим секцию заголовка. Добавьте этот код после функции mark_complete().
header_frame = tk.Frame(root, bg="#4a7c9e") header_frame.pack(fill=tk.X) header_label = tk.Label(header_frame, text="📝 My To-Do List", font=("Arial", 18, "bold"), bg="#4a7c9e", fg="white") header_label.pack(pady=15)
С помощью fill=tk.X, мы заставляем фрейм растягиваться по горизонтали на весь экран. Мы добавили виджет метки с некоторыми свойствами. Далее давайте поработаем с секцией ввода.
input_frame = tk.Frame(root, bg="#f0f0f0") input_frame.pack(pady=20) task_entry = tk.Entry(input_frame, width=35, font=("Arial", 13), bd=2, relief=tk.GROOVE) task_entry.pack(side=tk.LEFT, padx=10, ipady=5) task_entry.bind('<Return>', lambda event: add_task()) add_button = tk.Button(input_frame, text="Add Task", width=12, font=("Arial", 11, "bold"), bg="#5cb85c", fg="white", activebackground="#4cae4c", bd=0, cursor="hand2", command=add_task) add_button.pack(side=tk.LEFT)
Мы добавили границу к полю ввода и применили к ней эффект GROOVE. Мы также добавили немного стилей к кнопке. Далее — раздел с выпадающим списком.
list_frame = tk.Frame(root, bg="#f0f0f0") list_frame.pack(pady=10, padx=20) scrollbar = tk.Scrollbar(list_frame, orient=tk.VERTICAL) task_listbox = tk.Listbox(list_frame, width=55, height=14, font=("Arial", 11), bd=2, relief=tk.SUNKEN, selectmode=tk.SINGLE, activestyle='none', bg="white", selectbackground="#d4e6f1", selectforeground="black", yscrollcommand=scrollbar.set) scrollbar.config(command=task_listbox.yview) task_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
В рамке списка у нас появился новый виджет Scrollbar. Если список станет большим, он будет прокручиваться по вертикали. Мы также добавили некоторые свойства виджету Listbox, установив его цвета, стиль рамки и поведение прокрутки. Теперь давайте займёмся оставшимися кнопками.
button_frame = tk.Frame(root, bg="#f0f0f0") button_frame.pack(pady=20) mark_button = tk.Button(button_frame, text="✓ Mark Complete", width=15, font=("Arial", 10, "bold"), bg="#5bc0de", fg="white", activebackground="#46b8da", bd=0, cursor="hand2", command=mark_complete) mark_button.grid(row=0, column=0, padx=8) delete_button = tk.Button(button_frame, text="✕ Delete Task", width=15, font=("Arial", 10, "bold"), bg="#d9534f", fg="white", activebackground="#c9302c", bd=0, cursor="hand2", command=delete_task) delete_button.grid(row=0, column=1, padx=8) clear_button = tk.Button(button_frame, text="Clear All", width=15, font=("Arial", 10, "bold"), bg="#f0ad4e", fg="white", activebackground="#ec971f", bd=0, cursor="hand2", command=clear_all_tasks) clear_button.grid(row=0, column=2, padx=8)
Мы используем цвета и другие элементы оформления, соответствующие действию каждой кнопки, чтобы они визуально выделялись. Наконец, давайте добавим раздел с футером.
footer_label = tk.Label(root, text="Select a task and use buttons to manage it", font=("Arial", 9, "italic"), bg="#f0f0f0", fg="#666666") footer_label.pack(side=tk.BOTTOM, pady=10)
Здесь мы использовали виджет Label в качестве текстового блока. Когда вы запустите текущую версию, вам будет представлен красиво оформленный список дел.
Интерфейс теперь выглядит гораздо более отполированным и профессиональным. Полный код доступен в моем репозитории на GitHub для вашего удобства, так что не стесняйтесь его просматривать.
Вы можете добавить в существующее приложение гораздо больше функций, таких как операции с файлами, диалоговые окна сообщений и интеграция с базой данных, среди прочего. Если вас интересуют другие проекты на Tkinter, вы также можете создать трекер расходов. Также ознакомьтесь с документацией Tkinter для дальнейшего обучения.






Добавить комментарий