Выражаю большую признательность создателю программы Pyuibuilder, Полу.
Моё знакомство с этой программой началось с статьи на Дзене. Меня эта программа заинтересовала прежде всего тем, что она работает с библиотекой TKinter.
PyUIBuilder создает графические приложения, через drag-and-drop. (Drag-and-drop (с англ. «потащи и брось») — способ взаимодействия с элементами (объектами) интерфейса с помощью мыши, тачпада или сенсорного экрана. Это последовательное выполнение на элементах трёх операций: «захвата» (drag), перемещения и «отпускания» (drop) на другую позицию или поверх другого элемента интерфейса). То есть буквально перетаскиваешь элементы мышкой, расставляешь их где нужно, настраиваешь свойства, а на выходе получаешь готовый код на Python.
Так как я много времени уделяю изучению и созданию приложений при помощи стандартной библиотеки Python для GUI TKinter, поэтому я решил посветить эту статью прекрасному проекту PyUIBuilder.
Начнём с Главной странице этого проекта
На странице мы можем скачать приложение, узнать информацию или начать работу в демо версии онлайн.

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

Открываем программу.

Ждем открытия программы.

Разархивируем файл windows-latest.
В папке windows-latest, откроем файл PyUiBuilder-Setup-2.1.2
После открытия программы необходимо подтвердить почту, на которой мы зарегистрированы на сайте программы. Ввести ключ.
Указать путь до EXE файла установленного на вашем компьютере Python.
Далее Надо указать папку где будет храниться ваш проект созданный в PyUIBuilder.

Я создал папку 11, и разместил рядом с программой PyUIBuilder

Вот эту папку (11) я и указал для команды open existing workspace (откройте существующее рабочее пространство).
В ней будет созданна вложенная папка untitled project (проект без названия).

В ней находится вложенная папка .pyrunner

Далее находится вложенная папка .venv.
venv — это встроенный в Python модуль для создания виртуального окружения (virtual environment) — изолированного рабочего пространства для проектов.

В папке .venv находятся несколько пакок и файлов. Изучим их.

Pyvenv.cfg — это конфигурационный файл, обеспечивающий корректную работу виртуального окружения (venv, virtual environment) в Python.
Папка Scripts. Собственно, содержит содержит скрипты
В папка Lib. Находятся библиотеки необходимые для работы программы.
Папка Include. Место хранения заголовочных файлов.
В дальнейшем появится текстовый файл requirements. Файл requirements.txt в Python нужен для управления зависимостями проекта. Он содержит список Python-пакетов (библиотек), необходимых для работы проекта, и их версий.
Ну и тут будет находится сам исполнительный файл в Python.
Приступим к изучению программы.
Выглядит она так.

Посмотрим сколько программа поддерживает библиотек Python.
Из выпадающего списка мы можем выбрать tkinter, customTk или Pyside|Pyqt.

Можем выбрать дневную или ночную тему программы.

В верхней части программы посмотрим папку, где находится наш проект (папка untitled project).

Над рабочем полем (холстом) проекта расположены три команды.
Вы можете открыть элементы управления сеткой в левом верхнем углу рядом с иконками удаления
Чтобы включить прикрепление сетки, просто нажмите на кнопку включить кнопку, вы можете отрегулировать размер сетки с помощью ползунка
Вы также можете включить сетки для родительских виджетов, включив сетку виджетов.
1. Вывести виджеты на экран.
2. Чистый холст. Будьте внимательны перед тем как очистить поле проекта.
3. Сетка. Здесь настройки сетки рабочего поля проекта (привязка, показ сетки, цвет, дополнительная сетка на самом графическом приложении, при помощи бегунка можно выбрать размер сетки).

Главное меню программы.
File- Файл

New window- Новое окно. Создаёт новое окно для проекта.
Save desing- Сохранить дизайн. Сохраняет весь проект с графическими настройками.
Load desing- Загрузить дизайн. Загружает ранее созданный проект.
Settings- Настройки. Содержит две настройки. Выбор светлой или темной темы и путь к стартовому файлу Питона.
Logout- Выход из программы.
Exit- Выход
Edit- Редактировать.

Cut- Вырезать.
Copy- Копировать.
Paste- Вставить.
Select All- Выбрать всё.
View- Смотреть

Zoom in- Увеличить размер
Zoom out- Уменьшить размер
Reset zoom- Возврат размера
Clear canvas- Очистить полотно. Внимательно отнеситесь к стиранию полотна.
Help- Помощь

About- О проекте
Documentation- Документация
Community help- Помощь сообщества
Youtubu Tutorial- Инструкция в Ютубе
Report issue- Сообщить о проблеме
Reguest feature- Функция повторного запроса
Share Testimonial- Поделитесь отзывом
Latest Apdates- Последние обновления
License- EULA- Лицензия
Version details- Подробная информация о версии
Также дополнительно дублируется команда File

Левая боковая панель
Widgets- Виджеты.

Это отдельные компоненты, такие как метки, кнопки, рамки и т. д., которые помогают вам создавать свой интерфейс.
Plugins. Плагины.

Самостоятельные элементы дизайна.
Внизу после прокрутки всех списков плагинов, есть команда Request new plugins (запрашивать новые плагины).
Tree view. Древовидный вид.

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

Можно выбрать файл для загрузки. Актуально для загрузки иконок, картинок.
Templates. Шаблоны.

Готовые визуальные элементы, которые улучшают функционал создаваемого приложения.
Code Editor. Редактор кода.

Включает/выключает редактор кода, который расположен справа в программе.
About. Информация о проекте.

Discord invite. Приглашение в Discord.

Приобретение дополнительной лицензии для своей команды.


Поделитесь информацией и помогите ускорить разработку.

Docs. Документация о проекте.

Проект в github.

Правый верхний угол программы.
Предварительный просмотр.

Запускает скрипт в Питоне. И открывает созданное приложение.
Редактор кода.

Редактор кода призван помочь вам писать коды обработчиков событий.
Экспорт кода

Информация о виде тарифного плана проекта и Логин пользователя.

Холст
Место, куда вы перетаскиваете виджеты, называется холстом.
Что можно сделать на холсте.
Добавьте виджеты из боковой панели.
Масштабирование и перемещение с помощью мыши.
масштабирование с помощью клавиш +/-
Удаляйте виджеты с помощью del клавиши Enter или щелчка правой кнопкой мыши по виджету (на Mac: Function + Delete).
Для дублирования выбранного виджета можно использовать сочетание клавиш Ctrl/Cmd + D.
Название проекта
По умолчанию все проекты называются “untitled project”, вы можете изменить это в поле ввода заголовка рядом с полем экспорта кода.
Немного кода
Давайте посмотрим код, который создан по умолчанию, без внесения дополнительных виджетов в приложение. Выше я писал, что создал папку 11, и путь указал на неё. В этой папке создана папка untitled project, далее папка .pyrunner. В ней вместе с виртуальным окружением и находится файл Питон под названием main.
Посмотрим код:
# This code is generated using PyUIbuilder: https://pyuibuilder.com
import os
import tkinter as tk
from tkinter import ttk
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
main = tk.Tk()
main.title("Main Window")
main.config(bg="#E4E2E2")
main.geometry("700x345")
main.update_idletasks()
geometryX = 0
geometryY = 0
main.geometry("+%d+%d"%(geometryX, geometryY))
menu = tk.Menu(main)
main.config(menu=menu)
menu_0 = tk.Menu(menu, tearoff=0)
menu_0.add_command(label="New", command=lambda: print("New clicked"))
menu_0.add_command(label="Open", command=lambda: print("Open clicked"))
menu.add_cascade(label="File", menu=menu_0)
menu_1 = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Edit", menu=menu_1)
main.mainloop()
Рассмотрим каждую часть кода.
# This code is generated using PyUIbuilder: https://pyuibuilder.com
Ну здесь понятно, это комментарий.
import os
import os в Python — это команда, которая импортирует модуль os — встроенную библиотеку для взаимодействия с операционной системой.
Модуль os позволяет выполнять операции с файлами и директориями, получать информацию о файлах и папках (размер, права доступа, время модификации), работать с переменными окружения, выполнять системные команды и запускать дочерние процессы.
import tkinter as tk
import tkinter as tk в Python — это конструкция, которая импортирует модуль Tkinter (библиотеку для создания приложений с графическим интерфейсом, GUI) с именем tk.
from tkinter import ttk
from tkinter import ttk — это команда, которая импортирует модуль ttk (Themed Tk) в библиотеку Tkinter.
Модуль ttk содержит классы более стилизованных и современных виджетов. По умолчанию их внешний вид зависит от операционной системы. Основная идея ttk — отделить оформление виджета от описания его поведения.
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
Переменная __file__ возвращает путь, который был указан при импорте или запуске модуля.
Хотя __file__ является мощным инструментом, его использование в чистом виде может привести к проблемам переносимости. Более надёжный способ — комбинировать __file__ с функциями из модуля os.path.
Строка BASE_DIR = os.path.dirname(os.path.abspath(__file__)) в Python — это комбинация функций из модуля os.path для получения абсолютного пути к директории скрипта. Это позволяет строить все зависимые пути относительно местоположения самого скрипта, а не рабочей директории.
os.path.abspath() — преобразует относительный путь в абсолютный;
os.path.dirname(os.path.abspath(__file__)) позволит получить абсолютный путь к директории скрипта. Это даст возможность строить все зависимые пути относительно местоположения самого скрипта, а не рабочей директории.
Короче это нужно чтобы получить путь к файлу в Python.
main = tk.Tk()
Это команда в библиотеке Tkinter, которая создаёт главное окно приложения.
main.title(“Main Window”)
Метод title() — устанавливает заголовок окна.
main.config(bg=”#E4E2E2″)
Метод config() (configure()) в библиотеке Tkinter (Python) позволяет устанавливать параметры виджета после его создания. Это универсальный метод, который позволяет изменять различные аспекты виджета, такие как его размер, цвет, шрифт и многое другое. В данном случае Background (bg) — устанавливает цвет фона виджета.
main.geometry(“700×345”)
Метод geometry() — устанавливает размеры окна.
main.update_idletasks()
Метод update_idletasks() в библиотеке Tkinter приостанавливает выполнение кода, чтобы выполнить системные фоновые задачи. К ним относятся, например, вывод данных, программно занесённых в компоненты, на экран, перерисовка окна.
Обычно этот метод используется, если были внесены изменения в состояние приложения, и нужно, чтобы эти изменения были отображены на экране немедленно, не дожидаясь завершения сценария.
Важно помнить, что метод update_idletasks() следует использовать только если известно, что делается, так как он может привести к непредсказуемому поведению или циклу. Его не следует вызывать из обработчика событий или функции, которая вызывается из обработчика событий.
geometryX = 0
geometryY = 0
main.geometry(“+%d+%d”%(geometryX, geometryY))
Метод geometry() принимает строку, которая указывает на геометрию окна. В строке могут быть Ширина и высота окна (первые два параметра);
Координаты x и y на экране (последние два параметра).
Размер или координаты могут быть опущены: например, geometry(“600×400”) — только изменить размер, geometry(“+40+80”) — только переместить окно.
Важно: можно передать аргумент-переменную в метод geometry(), но он должен быть в форме (variable1) x (variable2), иначе возникнет ошибка.
Вот как раз здесь и переданы размеры через две переменные geometryX = 0 и geometryY = 0.
menu = tk.Menu(main)
Конструкция menu = tk.Menu(main) в библиотеке Tkinter (Python) создаёт экземпляр виджета Menu — главного меню окна приложения. Меню — это выпадающие списки под словами-пунктами, которые содержат команды, обычно выполняющие какие-либо действия или открывающие диалоговые окна.
main.config(menu=menu)
Метод main.config(menu=menu) в Tkinter позволяет установить меню (экземпляр виджета Menu) для текущего окна.
main.config(menu=menu)
menu — имя экземпляра меню, main — имя окна, на котором оно располагается.
Важно: параметр menu=menu нельзя вставлять, пока меню не будет объявлено и в него не будут введены команды.
menu_0 = tk.Menu(menu, tearoff=0)
Создается меню menu_0 с родителем menu.
Параметр tearoff=0 в строке menu_0 = tk.Menu(menu, tearoff=0) в Tkinter отключает возможность открепления меню от графического окна. По умолчанию значение tearoff — 1, и меню можно открепить с помощью пунктирной линии на границе.
menu_0.add_command(label=”New”, command=lambda: print(“New clicked”))
В коде menu_0.add_command(label=”New”, command=lambda: print(“New clicked”)) в Tkinter — это способ добавить элемент меню (пункт) с меткой «New» и командой, которая при нажатии на этот элемент выводит сообщение «New clicked» в консоль.
Метод add_command позволяет добавлять элементы в меню, задавая параметры: метку (label=”New”), и команду (command=lambda: print(“New clicked”)).
menu_0.add_command(label=”Open”, command=lambda: print(“Open clicked”))
Собственно, тоже что и выше
menu.add_cascade(label=”File“, menu=menu_0)
Метод menu.add_cascade(label=”File”, menu=menu_0) в Tkinter позволяет добавить меню «Файл» (file_menu) в главное меню (menubar). Это метод из класса виджета Menu, который позволяет создавать подменю и иерархически организовывать структуру меню.
Собственно мы сперва создали разделы меню New и Open, а потом привязали эти разделы к меню File.

menu_1 = tk.Menu(menu, tearoff=0)
menu.add_cascade(label=”Edit”, menu=menu_1)
Собственно, здесь создали следующий раздел Меню и добавили раздел Edit.

Некие зависимости создания подменю

main.mainloop()
Метод в библиотеке Tkinter (Python), который запускает бесконечный цикл обработки событий в приложении.
Он позволяет запускать приложение, ждать возникновения событий (нажатий клавиш, кликов мыши, изменения размера окна) и обрабатывать их, пока окно не закрыто.
Наконец-то закончили изучение стартового кода.
Вернёмся к изучению программы
Открытие и создание проекта
При повторном открытии программы откроется окно выбора рабочей области.

Мы можем открыть ранее созданный проект выбрав команду “Откройте существующее рабочее пространство”. Надо выбрать папку 11, где и находится проект untitled project и выбрать его.
Или создать новый проект, измените название и создастся новая папка с проектом, выберите команду Папка рабочей области, далее создание рабочего пространства.

Как и писал выше проекты у меня в папке 11, казав её в качестве папки рабочей области и изменив в названии на untitled project2 у меня при открытии программы появится новая папка (рис. 42).
Программа папки не перезаписывает проекты с одинаковым названием, приходится создавать проекты с новым названием.
Создание меню
Если навести курсор на поле с названиями разделов меню, то появится настройки по созданию новых разделов Меню.

И также создание вложенных подразделов Меню.
Тут всё интуитивно, можно прибавить, удалить и корректировать созданные разделы меню.

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

Настройки и атрибуты Главного окна.

Layout- Расположение (здесь он переведён как Макеты)
Каждый виджет, который может содержать дочерний виджет, имеет три различных варианта расположения. По умолчанию absolute- Абсолютное/Местоположение (гибкое) .
Flex (также известный как pack)
Grid- Сетка
Place- По месту

Родительские виджеты управляют компоновкой. Свойства компоновки, такие как положение в сетке, будут доступны дочерним виджетам в разделе grid-manager/flex-manager.
Добавление изображений к метке
Чтобы добавить изображение к метке, сначала перейдите в боковую панель -> Загрузки -> Загрузите файл изображения. Не забудьте сперва найти изображение и сохранить изображение в паку, чтобы его найти.

Теперь в разделе «Атрибуты метки» вы увидите опцию загрузки изображения. Выберите изображение из выпадающего списка.
Загруженные картинки будут видны в разделе Загрузки

Добавим в настройках Window Logo уже загруженную иконку (иконку загрузил маленькую размером 16х16).

Иконка появилась в макете

Кстати загруженные картинки находятся в папках untitled project- .pyrunner- assets.
Event Handlers. Обработчики событий
Выберем раздел Event Handlers. Обработчики событий- Add Event (Добавить событие)

Появятся два поля для выбора

В верхнем поле из выпадающего списка, выбираем вид события


Выбираем в качестве события “Нажатие левой кнопки мыши”.

Изменим код в редакторе кода.
Уберем заглушку pass для функции. Напишем тело функции print(“Privet”).

В нижнем окне появляется название функции, её и выбираем

Посмотрим на код.
У нас появилась функция click_handler.
def click_handler(event):
print(“Privet”)
Появился вызов функции
main.bind(“<Button-1>”, click_handler)
с событием для обработки левого нажатия кнопки мыши <Button-1>.

Обратите внимание.
Выше мы добавили иконку для заголовка.
Появился код. Для добавления изображения иконки.
main_img = Image.open(os.path.join(BASE_DIR, “assets”, “images”, “269295_pie-chart-icon.png”))
main_img = ImageTk.PhotoImage(main_img)
Добавим кнопку в приложение

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

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

Кстати, если мы добавим в редактор кода еще одну функцию click_handler0 для события и не будем вызывать событие. То ошибки при компиляции не будет.

Layout. Макеты
Выбрать можно в вкладки Layout.
Существует 4 основных макета. Макеты задаются родительскими виджетами. После установки макета каждый дочерний виджет будет использовать один и тот же макет для позиционирования. Единственное исключение — если вы включили абсолютное позиционирование на панели инструментов дочерних виджетов.
По умолчанию стоит значение absolute (абсолютный).
Если мы перетащим две кнопки в наше приложение. То можно передвигать расположение кнопок произвольно.

Посмотрим, что у нас с кодом?

Здесь и нас позиционирование. Place. Немного информации об этом методе.
Метод place() позволяет более точно настроить координаты и размеры виджета. Он принимает следующие параметры:
height и width: устанавливают соответственно высоту и ширину элемента в пикселях
relheight и relwidth: также задают соответственно высоту и ширину элемента, но в качестве значения используется число float в промежутке между 0.0 и 1.0, которое указывает на долю от высоты и ширины родительского контейнера
x и y: устанавливают смещение элемента по горизонтали и вертикали в пикселях соответственно относительно верхнего левого угла контейнера
relx и rely: также задают смещение элемента по горизонтали и вертикали, но в качестве значения используется число float в промежутке между 0.0 и 1.0, которое указывает на долю от высоты и ширины родительского контейнера
bordermode: задает формат границы элемента. Может принимать значение INSIDE (по умолчанию) и OUTSIDE
anchor: устанавливает опции растяжения элемента. Может принимать значения n, e, s, w, ne, nw, se, sw, c, которые являются сокращениями от North(север – вверх), South (юг – низ), East (восток – правая сторона), West (запад – левая сторона) и Center (по центру). Например, значение nw указывает на верхний левый угол
Выберем в вкладки Layout значение Flex.
Перенесём две кнопки. Но выделив одну кнопку, выберем из атрибутов этой кнопки раздел Absolute positioning, подтвердим галочкой выбор.

Посмотрим код.

Мы видим, что у одной кнопки значение позиционирования pack.
Этот метод принимает следующие параметры:
expand: если равно True, то виджет заполняет все пространство контейнера.
fill: определяет, будет ли виджет растягиваться, чтобы заполнить свободное пространство вокруг. Этот параметр может принимать следующие значения: NONE (по умолчанию, элемент не растягивается), X (элемент растягивается только по горизонтали), Y (элемент растягивается только по вертикали) и BOTH (элемент растягивается по вертикали и горизонтали).
anchor: помещает виджет в определенной части контейнера. Может принимать значения n, e, s, w, ne, nw, se, sw, c, которые являются сокращениями от Noth(север – вверх), South (юг – низ), East (восток – правая сторона), West (запад – левая сторона) и Center (по центру). Например, значение nw указывает на верхний левый угол
side: выравнивает виджет по одной из сторон контейнера. Может принимать значения: TOP (по умолчанию, выравнивается по верхней стороне контейнера), BOTTOM (выравнивание по нижней стороне), LEFT (выравнивание по левой стороне), RIGHT (выравнивание по правой стороне).
ipadx: устанавливает отступ содержимого виджета от его границы по горизонтали.
ipady: устанавливают отступ содержимого виджета от его границы по вертикали.
padx: устанавливает отступ виджета от границ контейнера по горизонтали.
pady: устанавливает отступ виджета от границ контейнера по вертикали.
Ну а у второй кнопки стало значение place (это позиционирование мы описали выше).
Выберем в Главном окне в разделе Layout, позиционирование Grid (сетка)
при этом в подразделе Direction выберем Horizontal. В подразделе Gap стоит значение 10.

Посмотрим код.

Мы видим что позиционирование у кнопок стало типа grid.
Метод grid() позволяет поместить виджет в определенную ячейку условной сетки или грида.
Метод grid применяет следующие параметры:
column: номер столбца, отсчет начинается с нуля
row: номер строки, отсчет начинается с нуля
columnspan: сколько столбцов должен занимать элемент
rowspan: сколько строк должен занимать элемент
ipadx и ipady: отступы по горизонтали и вертикали соответственно от границ элемента до его содержимого
padx и pady: отступы по горизонтали и вертикали соответственно от границ ячейки грида до границ элемента
sticky: выравнивание элемента в ячейке, если ячейка больше элемента. Может принимать значения n, e, s, w, ne, nw, se, sw, которые указывают соответствующее направление выравнивания
Есть дополнительные настройки для этого позиционирования


Ну и выберем последнее значение в Главном окне в разделе Layout, позиционирование Place
Перенесём кнопки в приложение
Посмотрим код.

Видим, что что кнопки имеют позиционирование pack.
При этом кнопки не имеют в настройках раздел Absolute positioning.
Все остальные атрибуты и настройки прекрасно мною описаны в разделе описания TKinter.
Сохранение проекта
При желании, можем сохранить проект. Выберем раздел главного меню- File-Save design.
Далее выбираем папку, в которую хотим сохранить проект. Проект будет сохранён в формате pyui.
