Как написать программу на python для windows

#статьи


  • 0

Знакомимся с библиотекой Tkinter — пишем на Python кросс-платформенный калькулятор, который рассчитывает вес человека.

Иллюстрация: Merry Mary для Skillbox Media

Антон Яценко

Изучает Python, его библиотеки и занимается анализом данных. Любит путешествовать в горах.

Десктопные приложения пишут на разных языках программирования: C++, C#, C, Python и других. Начинающим разработчикам проще всего использовать Python и его библиотеки для работы над графическими интерфейсами.

Одна из таких библиотек — Tkinter. Она входит в стандартный пакет Python и позволяет создавать приложения для Windows, mac OS и Linux. Давайте разберёмся, как устроена эта библиотека, и напишем десктопный калькулятор, помогающий рассчитать вес человека.

GUI (Graphical User Interface) — это графический интерфейс пользователя, оболочка программы, с которой мы взаимодействуем с помощью клавиатуры и мыши. На современных операционных системах почти все программы работают с графическим интерфейсом, и мы каждый день сталкиваемся с GUI: читаем статьи в браузере, набираем текст в редакторе или играем в игры.

Противоположность графическому интерфейсу — командная строка, позволяющая управлять приложением с помощью текстовых команд. Такой интерфейс реализован в терминале macOS и командной строке Windows.

Для работы с GUI в Python есть четыре библиотеки:

  • Tkinter;
  • Kivy;
  • Python QT;
  • wxPython.

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

Tkinter — это удобный интерфейс для работы со средствами Tk. Приложения, созданные на основе этой библиотеки, кросс-платформенные, то есть могут запускаться на разных операционных системах.

Схематично работу с Tkinter можно представить в виде четырёх шагов:

Скриншот: Tkinter

Что здесь происходит:

  • Мы подключаем библиотеку Tkinter с помощью директивы import.
  • Создаём главное окно приложения, в котором будут размещаться все графические элементы.
  • Добавляем виджеты — визуальные элементы, выполняющие определённые действия.
  • Создаём главный цикл событий — он включает в себя все события, происходящие при взаимодействии пользователя с интерфейсом.

Ключевые объекты в работе с Tkinter — виджеты. Это аналоги тегов из HTML, которые позволяют создавать интерактивные и неинтерактивные элементы, например надписи или кнопки. Всего их 18, но чаще всего используют следующие:

  • Button — кнопки;
  • Canvas — «холст», на котором рисуют графические фигуры;
  • Entry — виджет для создания полей ввода;
  • Label — контейнер для размещения текста или изображения;
  • Menu — виджет для создания пунктов меню.

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

Мы напишем калькулятор индекса массы тела. ИМТ — это важный медицинский показатель, который позволяет оценить, есть ли у человека избыточный вес или ожирение. Он рассчитывается по следующей формуле: ​​

Результаты расчётов оценивают с помощью специальной таблицы. У врачей она имеет много градаций, мы же воспользуемся упрощённой версией:

Изображение: Skillbox Media

Писать код на Python лучше всего в специальной IDE, например в PyCharm или Visual Studio Code. Они подсвечивают синтаксис и предлагают продолжение кода — это сильно упрощает работу программиста. Весь код из этой статьи мы писали в Visual Studio Code.

Библиотека Tkinter предустановлена в Python. Поэтому её нужно только импортировать:

import tkinter as tk

Теперь мы можем использовать любые модули из этой библиотеки.


Прежде чем писать код, необходимо ответить на несколько вопросов:

  • Какие данные мы хотим получить от пользователя и в каком виде?
  • Какое событие будет запускать расчёт ИМТ: нажатие кнопки, получение приложением всех необходимых данных или что-то другое?
  • Как будем показывать результат?

В нашем случае необходимо получить от пользователя вес и рост в виде целых чисел. При этом вес должен быть введён в килограммах, а рост — в сантиметрах. ИМТ будет рассчитываться по нажатии кнопки, а результат — выводиться во всплывающем окне в виде значения ИМТ и категории, к которой он относится.

Схематично графический интерфейс нашего калькулятора будет выглядеть так:

Скриншот: Tkinter / Skillbox Media

Теперь попробуем реализовать интерфейс и работу калькулятора с помощью Python и Tkinter.


После импорта библиотеки в Python загрузим её методы:

from tkinter import *
from tkinter import messagebox

Первая строка позволяет нам загрузить все методы Tkinter и использовать их в коде без ссылки на их наименование. Второй строкой мы явно импортируем метод messagebox, который будем использовать для вывода всплывающего окна с результатом. Это удобно, так как метод потребуется нам несколько раз.

Теперь создадим окно нашего приложения. Для этого воспользуемся модулем Tk. Приложение назовём «Калькулятор индекса массы тела (ИМТ)»:

window = Tk() #Создаём окно приложения.
window.title("Калькулятор индекса массы тела (ИМТ)") #Добавляем название приложения.

После запуска кода ничего не произойдёт. Это не ошибка. На самом деле код выполнился и окно закрылось. Необходимо явно указать, что окно приложения не должно закрываться до тех пор, пока пользователь сам не сделает этого. Для этого к коду добавим функцию window.mainloop (), указывающую на запуск цикла событий:

window.mainloop()

Запустив код, увидим экран приложения:

Скриншот: Tkinter / Skillbox Media

Мы не указали размер окна, поэтому название приложения не помещается в него полностью. Исправим это с помощью метода geometry:

window.geometry('400x300')

Теперь название приложения видно полностью:

Скриншот: Tkinter / Skillbox Media

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

  • pack — используется, когда мы работаем с контейнерами для элементов. Позволяет позиционировать кнопки, надписи или другие элементы внутри контейнеров.
  • place — позволяет позиционировать элементы, указывая точные координаты.
  • grid — размещает элементы по ячейкам условной сетки, разделяющей окно приложения.

Мы воспользуемся комбинацией методов pack и grid. Для начала создадим виджет Frame для размещения надписей, полей ввода и кнопок. Подробное описание работы виджета есть в документации. Мы же используем только два свойства: padx и pady.

Обозначим отступы по вертикали и горизонтали в 10 пикселей для элементов, которые будут расположены внутри Frame:

frame = Frame(
   window, #Обязательный параметр, который указывает окно для размещения Frame.
   padx = 10, #Задаём отступ по горизонтали.
   pady = 10 #Задаём отступ по вертикали.
)
frame.pack(expand=True) #Не забываем позиционировать виджет в окне. Здесь используется метод pack. С помощью свойства expand=True указываем, что Frame заполняет весь контейнер, созданный для него.


В окне приложения нам необходимо добавить три вида виджетов: поле для ввода информации (Entry), текстовые надписи (Label) и кнопку (Button).

Начнём с надписей. Воспользуемся виджетом Label:

height_lb = Label(
   frame,
   text="Введите свой рост (в см)  "
)
height_lb.grid(row=3, column=1)

Мы передаём виджету Label два параметра:

  • frame — используем заготовку виджета Frame, в которой уже настроены отступы по вертикали и горизонтали.
  • text — текст, который должен быть выведен на экран.

Для позиционирования виджета используем метод grid. Укажем, что текст должен располагаться в ячейке с координатами «3-я строка, 1-й столбец». Если запустим код, то увидим там единственный элемент:

Скриншот: Tkinter / Skillbox Media

Сейчас элемент расположен в центре окна, но он займёт правильное положение, когда мы напишем другие элементы.

Добавим вторую надпись о весе аналогичным образом, но при позиционировании в grid укажем следующую, четвёртую строку:

weight_lb = Label(
   frame,
   text="Введите свой вес (в кг)  ",
)
weight_lb.grid(row=4, column=1)

Запускаем код и смотрим на результат:

Скриншот: Tkinter / Skillbox Media

Теперь добавим поля для ввода пользовательской информации, используя виджет Entry:

height_tf = Entry(
   frame, #Используем нашу заготовку с настроенными отступами.
)
height_tf.grid(row=3, column=2)

Для позиционирования мы также воспользовались методом grid. Обратите внимание, что наш элемент должен быть расположен напротив надписи «Введите свой рост (в см)». Поэтому мы используем ячейку в той же строке, но уже во втором столбце. Запустим код и посмотрим на результат:

Скриншот: Tkinter / Skillbox Media

Всё получилось. Остаётся по аналогии добавить поле ввода веса:

weight_tf = Entry(
   frame,
)
weight_tf.grid(row=4, column=2, pady=5)

Посмотрим на результат:

Скриншот: Tkinter / Skillbox Media

Теперь добавим кнопку, которая будет запускать расчёт ИМТ. Сделаем это с помощью виджета Button:

cal_btn = Button(
   frame, #Заготовка с настроенными отступами.
   text='Рассчитать ИМТ', #Надпись на кнопке.
)
cal_btn.grid(row=5, column=2) #Размещаем кнопку в ячейке, расположенной ниже, чем наши надписи, но во втором столбце, то есть под ячейками для ввода информации.

Посмотрим на результат:

Скриншот: Tkinter / Skillbox Media

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


Напишем простую функцию и разберём её построчно:

def calculate_bmi(): #Объявляем функцию.
   kg = int(weight_tf.get()) #С помощью метода .get получаем из поля ввода с именем weight_tf значение веса, которое ввёл пользователь и конвертируем в целое число с помощью int().
   m = int(height_tf.get())/100 #С помощью метода .get получаем из поля ввода с именем height_tf значение роста и конвертируем в целое число с помощью int(). Обязательно делим его на 100, так как пользователь вводит рост в сантиметрах, а в формуле для расчёта ИМТ используются метры.
   bmi = kg/(m*m)#Рассчитываем значение индекса массы тела.
   bmi = round(bmi, 1) #Округляем результат до одного знака после запятой.

Функция готова. Но теперь нам необходимо оценить полученный результат расчёта и вывести сообщение для пользователя.


Дополним нашу функцию calculate_bmi. Воспользуемся условным оператором if, чтобы учесть полученные значения ИМТ, и методом Tkinter messagebox для отображения сообщения во всплывающем окне:

if bmi < 18.5:
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует недостаточному весу')
   elif (bmi > 18.5) and (bmi < 24.9):
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует нормальному весу')
   elif (bmi > 24.9) and (bmi < 29.9):
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует избыточному весу')
   else:
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует ожирению')

Остаётся последний шаг — наша функция должна запускаться при нажатии на кнопку «Рассчитать ИМТ». Для этого добавим свойство command в виджет Button:

cal_btn = Button(
   frame,
   text='Рассчитать ИМТ',
   command=calculate_bmi #Позволяет запустить событие с функцией при нажатии на кнопку.
)
cal_btn.grid(row=5, column=2)

Запустим код и посмотрим на результат:

Источник: Tkinter / Skillbox Media

Всё работает. Функция получает данные из полей ввода и рассчитывает индекс массы тела, показывая результат на экране.

from tkinter import *
from tkinter import messagebox
 
def calculate_bmi():
   kg = int(weight_tf.get())
   m = int(height_tf.get())/100
   bmi = kg/(m*m)
   bmi = round(bmi, 1)
 
   if bmi < 18.5:
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует недостаточному весу')
   elif (bmi > 18.5) and (bmi < 24.9):
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует нормальному весу')
   elif (bmi > 24.9) and (bmi < 29.9):
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует избыточному весу')
   else:
       messagebox.showinfo('bmi-pythonguides', f'ИМТ = {bmi} соответствует ожирению')  
 
window = Tk()
window.title('Калькулятор индекса массы тела (ИМТ)')
window.geometry('400x300')
 
 
frame = Frame(
   window,
   padx=10,
   pady=10
)
frame.pack(expand=True)
 
 
height_lb = Label(
   frame,
   text="Введите свой рост (в см)  "
)
height_lb.grid(row=3, column=1)
 
weight_lb = Label(
   frame,
   text="Введите свой вес (в кг)  ",
)
weight_lb.grid(row=4, column=1)
 
height_tf = Entry(
   frame,
)
height_tf.grid(row=3, column=2, pady=5)
 
weight_tf = Entry(
   frame,
)
weight_tf.grid(row=4, column=2, pady=5)
 
cal_btn = Button(
   frame,
   text='Рассчитать ИМТ',
   command=calculate_bmi
)
cal_btn.grid(row=5, column=2)
 
window.mainloop()

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

  • Python GUI Programming with Tkinter. Develop responsive and powerful GUI applications with Tkinter, Алан Мур.
  • Tkinter GUI Programming by Example, Дэвид Лав.

Бесплатный курс: «Быстрый старт в Python»
Начать учиться

Пройдите тест, узнайте какой профессии подходите

Работать самостоятельно и не зависеть от других

Работать в команде и рассчитывать на помощь коллег

Организовывать и контролировать процесс работы

Введение в разработку приложений для ПК на Python

Python — это мощный и гибкий язык программирования, который идеально подходит для разработки приложений для ПК. Благодаря своей простоте и обширной библиотеке, Python позволяет создавать как простые утилиты, так и сложные приложения с графическим интерфейсом. В этой статье мы рассмотрим основные шаги, необходимые для разработки приложений для ПК на Python, начиная с установки окружения и заканчивая сборкой и распространением готового продукта.

Python имеет множество преимуществ, которые делают его отличным выбором для разработки приложений. Во-первых, это кроссплатформенность: приложения, написанные на Python, могут работать на Windows, macOS и Linux без значительных изменений в коде. Во-вторых, Python обладает богатой экосистемой библиотек и фреймворков, которые упрощают разработку и позволяют сосредоточиться на логике приложения, а не на низкоуровневых деталях.

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

Кинга Идем в IT: пошаговый план для смены профессии

Установка и настройка окружения

Перед тем как начать разработку, необходимо установить Python и настроить рабочее окружение. Для этого выполните следующие шаги:

  1. Скачайте и установите Python: Перейдите на официальный сайт Python (https://www.python.org/) и скачайте последнюю версию. Установите Python, следуя инструкциям установщика. Убедитесь, что вы установили Python с опцией добавления в PATH, чтобы иметь возможность запускать его из командной строки.

  2. Установите виртуальное окружение: Виртуальные окружения позволяют изолировать зависимости вашего проекта. Это особенно полезно, если вы работаете над несколькими проектами, которые требуют разных версий библиотек. Для создания виртуального окружения выполните команду:

    Активируйте виртуальное окружение:
    – На Windows:
    – На macOS и Linux:

  3. Установите необходимые библиотеки: Для разработки графических интерфейсов на Python часто используется библиотека Tkinter, которая входит в стандартную библиотеку Python. Дополнительно можно установить PyInstaller для сборки приложения:

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

Создание простого графического интерфейса с Tkinter

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

Пример простого окна

Создадим простое окно с кнопкой и текстовым полем. Этот пример поможет вам понять основные принципы работы с Tkinter и создать базовый интерфейс для вашего приложения:

Этот код создает окно с заголовком «Простое приложение», меткой и кнопкой. При нажатии на кнопку текст метки изменяется на «Привет, мир!». Основные элементы интерфейса, такие как окна, метки и кнопки, создаются с помощью соответствующих классов Tkinter. Метод pack() используется для размещения элементов в окне.

Дополнительные элементы интерфейса

Помимо меток и кнопок, Tkinter предоставляет множество других элементов интерфейса, таких как текстовые поля, флажки, радиокнопки и списки. Рассмотрим пример с добавлением текстового поля и флажка:

В этом примере добавлено текстовое поле для ввода имени пользователя и флажок. При нажатии на кнопку приложение выводит приветствие с именем пользователя и состоянием флажка.

Работа с событиями и обработчиками

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

Пример обработки событий

Добавим обработку ввода текста в наше приложение. Это позволит нам реагировать на действия пользователя и изменять интерфейс в зависимости от введенных данных:

Теперь приложение запрашивает у пользователя имя и выводит приветствие с этим именем при нажатии на кнопку. Обработка событий в Tkinter осуществляется с помощью связывания функций-обработчиков с элементами интерфейса. В данном случае функция on_button_click вызывается при нажатии на кнопку.

Обработка дополнительных событий

Помимо нажатий кнопок, Tkinter позволяет обрабатывать множество других событий, таких как движение мыши, нажатие клавиш и изменение состояния элементов интерфейса. Рассмотрим пример обработки события нажатия клавиши:

В этом примере приложение реагирует на нажатие любой клавиши и выводит символ нажатой клавиши в метке. Метод bind используется для связывания события с функцией-обработчиком.

Сборка и распространение приложения

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

Сборка приложения с PyInstaller

  1. Установите PyInstaller (если еще не установили):

    bash
    pip install pyinstaller

  2. Соберите приложение:

    bash
    pyinstaller --onefile --windowed your_script.py

    Параметры --onefile и --windowed создают один исполняемый файл без консольного окна. PyInstaller анализирует ваш скрипт и все его зависимости, а затем упаковывает их в один исполняемый файл, который можно запускать на целевой системе без необходимости установки Python.

Настройка сборки

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

  1. Создайте файл спецификации:

    В этом примере используется параметр `—icon` для указания иконки приложения и `—add-data` для включения папки с данными.

  2. Редактирование файла спецификации: После первого запуска PyInstaller создаст файл спецификации (.spec), который можно отредактировать для более тонкой настройки сборки. Откройте файл .spec и внесите необходимые изменения.

Распространение приложения

Для распространения приложения можно использовать различные методы:

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

  • Создание установщика: Используйте инструменты, такие как Inno Setup (для Windows) или Platypus (для macOS), чтобы создать удобный установщик для вашего приложения. Установщик позволяет пользователям легко установить и настроить ваше приложение, а также может включать дополнительные файлы и зависимости.

  • Публикация на GitHub: Создайте репозиторий на GitHub и загрузите туда исходный код и исполняемый файл. Это позволит пользователям легко найти и скачать ваше приложение. Вы также можете использовать GitHub Releases для публикации новых версий приложения и предоставления пользователям удобного интерфейса для загрузки.

  • Использование платформ для распространения ПО: Рассмотрите возможность публикации вашего приложения на платформах, таких как Microsoft Store, Mac App Store или Linux Package Managers. Это может потребовать дополнительных усилий для соответствия требованиям платформы, но обеспечит более широкую аудиторию и удобство для пользователей.

Заключение

Разработка приложений для ПК на Python — это увлекательный и полезный процесс. С помощью Python и библиотек, таких как Tkinter и PyInstaller, можно быстро создавать и распространять приложения с графическим интерфейсом. Надеюсь, это руководство помогло вам сделать первые шаги в этой области. Удачи в разработке! 😉

Читайте также

Эта статья предназначена для тех, кто только начинает своё знакомство с созданием приложений с графическим интерфейсом (GUI) на Python. В ней мы рассмотрим основы использования PyQt в связке с Qt Designer. Шаг за шагом мы создадим простое Python GUI приложение, которое будет отображать содержимое выбранной директории.

Что нам потребуется

Нам понадобятся PyQt и Qt Designer, ну и Python, само собой.

В этой статье используется PyQt5 с Python 3, но особых различий между PyQt и PySide или их версиями для Python 2 нет.

Windows: PyQt можно скачать здесь. В комплекте с ним идёт Qt Designer.

macOS: Вы можете установить PyQt с помощью Homebrew:

$ brew install pyqt5

Скачать пакет с большинством компонентов и инструментов Qt, который содержит Qt Designer, можно по этой ссылке.

Linux: Всё нужное, вероятно, есть в репозиториях вашего дистрибутива. Qt Designer можно установить из Центра Приложений, но PyQt придётся устанавливать через терминал. Установить всё, что нам понадобится, одной командой можно, например, так:

			# для Fedora:
$ sudo dnf install python3-qt5 qt-creator
# для Debian/Ubuntu:
$ sudo apt install python3-qt5 pyqt5-dev-tools qtcreator
		

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

			$ pyuic5
Error: one input ui-file must be specified
		

Если вы видите сообщение, что такой команды нет или что-то в таком роде, попробуйте загуглить решение проблемы для вашей операционной системы и версии PyQt.

Если вы используете Windows, то, скорее всего, путь C:\Python36\Scripts (измените 36 на вашу версию Python) не прописан в вашем PATH. Загляните в этот тред на Stack Overflow, чтобы узнать, как решить проблему.

Дизайн

Основы

Теперь, когда у нас всё готово к работе, давайте начнём с простого дизайна.

Откройте Qt Designer, где вы увидите диалог новой формы, выберите Main Window и нажмите Create.

Python GUI: создаём простое приложение с PyQt и Qt Designer 1

После этого у вас должна появиться форма — шаблон для окна, размер которого можно менять и куда можно вставлять объекты из окна виджетов и т.д. Ознакомьтесь с интерфейсом, он довольно простой.

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

Все элементы формы и их иерархия по умолчанию отображаются в правой части окна Qt Designer под названием Object Inspector. Вы с лёгкостью можете удалять объекты, кликая по ним правой кнопкой мыши в этом окне. Или же вы можете выбрать их в основной форме и нажать клавишу DEL на клавиатуре.

Python GUI: создаём простое приложение с PyQt и Qt Designer 2

В итоге мы имеем почти пустую форму. Единственный оставшийся объект — centralwidget, но он нам понадобится, поэтому с ним мы ничего не будем делать.

Теперь перетащите куда-нибудь в основную форму List Widget (не List View) и Push Button из Widget Box.

Макеты

Вместо использования фиксированных позиций и размеров элементов в приложении лучше использовать макеты. Фиксированные позиции и размеры у вас будут выглядеть хорошо (пока вы не измените размер окна), но вы никогда не можете быть уверены, что всё будет точно так же на других машинах и/или операционных системах.

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

Давайте создадим нашу первую форму без использования макетов. Перетащите список и кнопку в форме и измените их размер, чтобы вышло вот так:

Python GUI: создаём простое приложение с PyQt и Qt Designer 3

Теперь в меню Qt Designer нажмите Form, затем выберите Preview и увидите что-то похожее на скриншот выше. Выглядит хорошо, не так ли? Но вот что случится, когда мы изменим размер окна:

Python GUI: создаём простое приложение с PyQt и Qt Designer 4

Наши объекты остались на тех же местах и сохранили свои размеры, несмотря на то что размер основного окна изменился и кнопку почти не видно. Вот поэтому в большинстве случаев стоит использовать макеты. Конечно, бывают случаи, когда вам, например, нужна фиксированная или минимальная/максимальная ширина объекта. Но вообще при разработке приложения лучше использовать макеты.

Основное окно уже поддерживает макеты, поэтому нам ничего не нужно добавлять в нашу форму. Просто кликните правой кнопкой мыши по Main Window в Object Inspector и выберите Lay outLay out vertically. Также вы можете кликнуть правой кнопкой по пустой области в форме и выбрать те же опции:

Python GUI: создаём простое приложение с PyQt и Qt Designer 5

Ваши элементы должны быть в том же порядке, что и до внесённых изменений, но если это не так, то просто перетащите их на нужное место.

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

Python GUI: создаём простое приложение с PyQt и Qt Designer 6

Если у вас не получается переместить элемент в главном окне, вы можете сделать это в окне Object Inspector.

Последние штрихи

Теперь, благодаря вертикальному размещению, наши элементы выровнены правильно. Единственное, что осталось сделать (но не обязательно), — изменить имя элементов и их текст.

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

Свойства элементов можно изменить в разделе Property Editor.

Подсказка: вы можете менять размер, передвигать или добавлять часто используемые элементы в интерфейс Qt Designer для ускорения рабочего процесса. Вы можете добавлять скрытые/закрытые части интерфейса через пункт меню View.

Нажмите на кнопку, которую вы добавили в форму. Теперь в Property Editor вы должны видеть все свойства этого элемента. В данный момент нас интересуют objectName и text в разделе QAbstractButton. Вы можете сворачивать разделы в Property Editor нажатием по названию раздела.

Измените значение objectName на btnBrowse и text на Выберите папку.

Должно получиться так:

Python GUI: создаём простое приложение с PyQt и Qt Designer 7

Именем объекта списка является listWidget, что вполне подходит в данном случае.

Сохраните дизайн как design.ui в папке проекта.

Превращаем дизайн в код

Конечно, можно использовать .ui-файлы напрямую из Python-кода, однако есть и другой путь, который может показаться легче. Можно конвертировать код .ui-файла в Python-файл, который мы потом сможем импортировать и использовать. Для этого мы используем команду pyuic5 из терминала/командной строки.

Чтобы конвертировать .ui-файл в Python-файл с названием design.py, используйте следующую команду:

			$ pyuic5 path/to/design.ui -o output/path/to/design.py
		

Пишем код

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

Создайте файл main.py в папке, где находится design.py.

Используем дизайн

Для Python GUI приложения понадобятся следующие модули:

			import sys  # sys нужен для передачи argv в QApplication
from PyQt5 import QtWidgets
		

Также нам нужен код дизайна, который мы создали ранее, поэтому его мы тоже импортируем:

			import design  # Это наш конвертированный файл дизайна
		

Так как файл с дизайном будет полностью перезаписываться каждый раз при изменении дизайна, мы не будем изменять его. Вместо этого мы создадим новый класс ExampleApp, который объединим с кодом дизайна для использования всех его функций:

			class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        # Это здесь нужно для доступа к переменным, методам
        # и т.д. в файле design.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна
		

В этом классе мы будем взаимодействовать с элементами интерфейса, добавлять соединения и всё остальное, что нам потребуется. Но для начала нам нужно инициализировать класс при запуске кода. С этим мы разберёмся в функции main():

			def main():
    app = QtWidgets.QApplication(sys.argv)  # Новый экземпляр QApplication
    window = ExampleApp()  # Создаём объект класса ExampleApp
    window.show()  # Показываем окно
    app.exec_()  # и запускаем приложение
		

И чтобы выполнить эту функцию, мы воспользуемся привычной конструкцией:

			if __name__ == '__main__':  # Если мы запускаем файл напрямую, а не импортируем
    main()  # то запускаем функцию main()
		

В итоге main.py выглядит таким образом:

			import sys  # sys нужен для передачи argv в QApplication
from PyQt5 import QtWidgets
import design  # Это наш конвертированный файл дизайна

class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        # Это здесь нужно для доступа к переменным, методам
        # и т.д. в файле design.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна

def main():
    app = QtWidgets.QApplication(sys.argv)  # Новый экземпляр QApplication
    window = ExampleApp()  # Создаём объект класса ExampleApp
    window.show()  # Показываем окно
    app.exec_()  # и запускаем приложение

if __name__ == '__main__':  # Если мы запускаем файл напрямую, а не импортируем
    main()  # то запускаем функцию main()
		

Если запустить этот код: $ python3 main.py, то наше приложение запустится!

Python GUI: создаём простое приложение с PyQt и Qt Designer 8

Но нажатие на кнопку ничего не даёт, поэтому нам придётся с этим разобраться.

Добавляем функциональность в наше Python GUI приложение

Примечание Весь дальнейший код пишется внутри класса ExampleApp.

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

			self.btnBrowse.clicked.connect(self.browse_folder)
		

Добавьте эту строку в метод __init__ класса ExampleApp, чтобы выполнить привязку при запуске приложения. А теперь взглянем на неё поближе:

  • self.btnBrowse: здесь btnBrowse — имя объекта, который мы определили в Qt Designer. self говорит само за себя и означает принадлежность к текущему классу;
  • clicked — событие, которое мы хотим привязать. У разных элементов разные события, например, у виджетов списка есть itemSelectionChanged и т.д.;
  • connect() — метод, который привязывает событие к вызову переданной функции;
  • self.browse_folder — просто функция (метод), которую мы описали в классе ExampleApp.

Для открытия диалога выбора папки мы можем использовать встроенный метод QtWidgets.QFileDialog.getExistingDirectory:

			directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку")
		

Если пользователь выберет директорию, переменной directory присвоится абсолютный путь к выбранной директории, в противном случае она будет равна None. Чтобы не выполнять код дальше, если пользователь закроет диалог, мы используем команду if directory:.

Для отображения содержимого директории нам нужно импортировать os:

И получить список содержимого следующим образом:

Для добавления элементов в listWidget мы используем метод addItem(), а для удаления всех элементов у нас есть self.listWidget.clear().

В итоге функция browse_folder должна выглядеть так:

			def browse_folder(self):
    self.listWidget.clear()  # На случай, если в списке уже есть элементы
    directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку")
    # открыть диалог выбора директории и установить значение переменной
    # равной пути к выбранной директории

    if directory:  # не продолжать выполнение, если пользователь не выбрал директорию
        for file_name in os.listdir(directory):  # для каждого файла в директории
            self.listWidget.addItem(file_name)   # добавить файл в listWidget
		

Теперь, если запустить приложение, нажать на кнопку и выбрать директорию, мы увидим:

Python GUI: создаём простое приложение с PyQt и Qt Designer 9

Так выглядит весь код нашего Python GUI приложения:

			import sys  # sys нужен для передачи argv в QApplication
import os  # Отсюда нам понадобятся методы для отображения содержимого директорий

from PyQt5 import QtWidgets

import design  # Это наш конвертированный файл дизайна

class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        # Это здесь нужно для доступа к переменным, методам
        # и т.д. в файле design.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна
        self.btnBrowse.clicked.connect(self.browse_folder)  # Выполнить функцию browse_folder
                                                            # при нажатии кнопки

    def browse_folder(self):
        self.listWidget.clear()  # На случай, если в списке уже есть элементы
        directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку")
        # открыть диалог выбора директории и установить значение переменной
        # равной пути к выбранной директории

        if directory:  # не продолжать выполнение, если пользователь не выбрал директорию
            for file_name in os.listdir(directory):  # для каждого файла в директории
                self.listWidget.addItem(file_name)   # добавить файл в listWidget

def main():
    app = QtWidgets.QApplication(sys.argv)  # Новый экземпляр QApplication
    window = ExampleApp()  # Создаём объект класса ExampleApp
    window.show()  # Показываем окно
    app.exec_()  # и запускаем приложение

if __name__ == '__main__':  # Если мы запускаем файл напрямую, а не импортируем
    main()  # то запускаем функцию main()
		

Это были основы использования Qt Designer и PyQt для разработки Python GUI приложения. Теперь вы можете спокойно изменять дизайн приложения и использовать команду pyuic5 без страха потерять написанный код.

Почему Desktop-приложение на Питоне?

Если Вы, как и я, решили впервые взглянуть в сторону Python после нескольких попыток изучения С++/C# то скорее всего первым проектом станет desktop-приложение. Отходя от темы скажу что тяга к изучению этих языков была безнадежно утрачена в виду классического преподавания в духе «лишь бы сдали» и бесчисленных однотипных и монотонных лекций. Как я сказал выше хоть и на начальном уровне, но я всё же касался разработки приложений для Windows и поэтому мне хотелось посмотреть на принципы работы питона сначала отсюда(а не прыгать в django и прочие мощные фреймворки). Должен предупредить — в статье не приводятся выдержки из кода и она является скорее выражением моих эмоций, полученных за этот проект.

Какое приложение создавать?

В этом я не сомневался ни секунды и сразу выбрал — ТАЙМЕР! Я люблю засыпать под звуки фильмов с различных ресурсов, но то что после их окончания комп работал лишние 6 часов меня решительно не устраивало. Я конечно знаю про существование разного рода приложений с подобным функционалом(например SMtimer), но во-первых его UX/UI это просто привет нулевым, а во-вторых хотелось всё-таки своё.

Непосредственно сам SMtimer

Непосредственно сам SMtimer

Задачи намечены — время действовать

Посмотрев полтора гайда с youtube преисполнился и написал первый прототип с использованием стандартной библиотеки tkinter. Выглядело это весьма сомнительно с точки зрения того же UX/UI, но это уже было что-то

Первая версия моего многострадального проекта

Тут каждый может заметить и сказать «но ведь это ещё хуже чем SMtimer» и будут правы, в целом и меня посещали такие мысли и я решил обратиться к поиску чего-то что сможет сделать из этого адекватное приложение которым я смогу пользоваться без зазрения совести.

CustomTkinter или как я пытался познать дзен

После недолгого поиска я нашел его — CustomTkinter. Он обещал буквально сделать из моего прототипа приложение, которое будто изначально было в Windows 10. Непосредственно exampl’ы вы можете смотреть ниже:

Темная тема "example" от CustomTkinter

Темная тема «example» от CustomTkinter
Соответственно светлая тема "example" от CustomTkinter

Соответственно светлая тема «example» от CustomTkinter

Вдобавок к этому библиотека обещала и минимальные правки кода для переноса моего «прототипа» на эту прелесть, но мне предстоял ещё большой путь в понимании как это тут работает…

Куча проблем и нехватка понимания

Именно так бы я описал свой путь в познании этой библиотеки. Буквально пытаясь взаимодействовать с ней я понял как устроены типы данных Python(да, может показаться смешным, но когда впервые встречаешь NoneType слегка удивляешься), понял как взаимодействовать с объектами классов и собственно разделять код проекта на функциональные блоки (что до этого мне казалось чем-то странным). Но для того чтобы понять насколько всё было грустно в моих познаниях — вот референс который я запилил от безысходности( на тот момент я хотел получить хотя бы это):

Как можно заметить даже цвет в тупую залит в Paint

Как можно заметить даже цвет в тупую залит в Paint

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

Пусть и работающая на коленях, но РАБОТАЮЩАЯ версия

Получив это я уже был рад, что не сдался и приступил к починке расположения всех объектов по экрану. Однако следует упомянуть о «маленькая проблема» — в CustomTkinter нет SpinBox, а значит вводить данные было нужно либо с клавиатуры, либо искать как сделать этот самый SpinBox самому. Выбор пал на второй вариант, на сайте, посвященном самому ctk автор сделал FloatSpinBox, доработав который я уже мог получить то что хотел.

Собственно FloatSpinBox

Собственно FloatSpinBox

Главным его косяком было отсутствие реакции на колёсико мышки — для меня это было критично — нажимать 32 раза для установки минут меня не прельщало и я решил допилить его самостоятельно:

  1. Добавил min и max value — теперь я мог использовать этот класс и для минут и для часов (сначала я просто наспамил несколько классов где вручную установил ограничения для каждого из них)

  2. Реакция на колёсико мышки теперь охватывала весь SpinBox и это было чудесно. Если просто повесить обработчик на self.bind(«MouseWheel», self.on_mouse_wheel)» то срабатывание будет только на границах entry и элементах кнопок, что просто ужасно.

  3. Ну и конечно реализовал прокрутку в обратную сторону. Это так странно делать то что обычно реализовано уже за тебя.

    Ну и немного поиграл с темами самого customtkinter:

Рождение первого адекватного прототипа

Рождение первого адекватного прототипа
Темы которые я нашел на просторах github

Темы которые я нашел на просторах github

Наконец то, что я и хотел получить

Теперь я решил сделать вывод времени до срабатывания. Я прорабатывал разные версии этого таймера и пришел к тому что запилил TimeBox. Главное отличие — никаких кнопок. Вывод конечно же стал гораздо веселее.

Предрелизная версия моего таймера

Предрелизная версия моего таймера

После того как я насмотрелся на кастомные темы с просторов github я решил, что мне такого ужаса точно не нужно и вернулся к истокам — стандартной зелёной теме. Победив эффект циклопа (даже 3х) я добавил переключение тем и поправил логику приложения — перезагрузка. выключение, сон и блокировка работают на ура ну и два вида условий таймера — через промежуток времени и В конкретное время. Я был полностью доволен и буквально счастлив что теперь мне не нужно каждый день идти в планировщик заданий и выставлять время выключения вручную! Но тут я увидел то, что впоследствии переведет меня из Notepad++ (да, да, именно там я и писал свой проект до этого момента) в PyCharm. Это была библиотечка pywinstyles, обещающая эффекты прозрачности как из win7 но в стиле десятки. То что нужно.

Sample Customtkinter но с Pywinstyles

Sample Customtkinter но с Pywinstyles

Мне показалось это просто идеальным дополнением моей програмки. Запускаешь поверх фильма и не мешает и знаешь сколько времени осталось — красота. Но полное отсутствие документации и внятных sampl’ов заставило заново пересмотреть перспективы проекта. Я написал автору pywinstyles и с его описанием я таки смог заставить работать это всё вместе:

Итоговые версии с pywinstyles

Итоговые версии с pywinstyles

Если тут есть такие же странные люди, которые решат потрогать pywinstyles — будьте готовы к множеству проблем. К примеру после смены темы на прозрачную назад вернуть никак. Только перезапуск. У main_frame от ctk тут беловатый фон, что заставляет программу «сиять» на светлых фонах.

Выводы

Я получил то, что хотел и кучу необходимого опыта сверху. В будущем хочу реализовать автоматическую остановку таймера. В случае если фильм ставиться на паузу то и сам таймер останавливается. Как это реализовать при просмотре фильма из браузера я пока не знаю, но если у Вас есть идеи — с радостью почитаю.

Потрогать версию без pywinstyles можно тут


A
desktop application is a software program that is installed and executed locally on a personal computer or workstation.

Unlike web applications, which run within a web browser, desktop applications are designed to be run directly on the user’s desktop environment, interacting with the operating system and other software installed on the computer.

Desktop applications can range from simple utilities to complex productivity tools and multimedia software.

They typically provide a user interface through windows, buttons, menus, and other graphical elements, allowing users to interact with the application and perform various tasks.

Some examples of desktop applications that can be developed include word processors, spreadsheets, graphic design software, video editors, games, ERP systems, CRM apps, and email clients.

These applications are installed on the user’s computer, which means they can often run offline without requiring an internet connection, although some may also have online features or require internet access for certain functions.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Windows 10 загрузка пользователя по умолчанию
  • Программа uninstaller для windows
  • За что отвечает реестр windows
  • Windows 10 разные обои на разных рабочих столах
  • Рейтинг антивирусов для windows server