Ultimate Fighting Championship
- 1 year ago
- 0
- 0
Ultimate++ (известен также как U++ и UPP ) — кросс-платформенный инструментарий разработки ПО на языке программирования C++ . Целью U++ является уменьшение сложности типичных десктопных приложений за счёт интенсивного использования особенностей C++. Работает под Linux / X11 , BSD / X11 , Windows и, начиная с версии 2019.1 macOS . Поддержка разработки для Android находится в состоянии разработки .
Проект развивается с 1999 года, ядро Ultimate++ team составляют чешские программисты.
Представляет собой фреймворк, призванный не только обеспечить быструю разработку GUI -приложений, но и, в идеале, заменить все сторонние библиотеки и инструменты для C++, включая даже STL (роль которой в U++ выполняет библиотека NTL — New Template Library). Этим Ultimate++ похоже на Qt , хотя идёт в данном направлении ещё дальше. Однако UPP, в отличие от Qt, не расширяет C++ с помощью нестандартных макрообработчиков исходного текста, все высокоуровневые средства этого фреймворка, выглядящие как расширения языка C++, выполнены за счёт стандартных механизмов вроде и макросов . Это даёт возможность использовать при создании интерфейса механизм шаблонов, что позволяет добиться компактного и легко читаемого кода. По лаконичности код, написанный с использованием U++, напоминает современные скриптовые языки « сверхвысокого уровня ».
В состав Ultimate++ входят следующие библиотеки:
Все эти компоненты рассчитаны на совместное использование и не предназначены для работы по отдельности. Ultimate++ использует специфическую организацию кода в виде так называемых «пакетов», поэтому разработка с Ultimate++, но без использования TheIDE вряд ли [ уточнить ] возможна на практике.
Работа с исходными текстами в U++ происходит в категориях пакетов (идея, привычная разработчикам на Delphi или Lazarus ), а не разрозненных библиотек и исходных файлов. Технически пакет — это просто содержащий исходные коды отдельный каталог, в котором также находится файл-описание с расширением upp. .upp-файлы обновляются IDE автоматически и являются аналогами make -файлов с описанием зависимостей и флагов компиляции.
При подключении пакета к проекту IDE установит необходимые пути и флаги для компилятора автоматически. Сам проект также является пакетом, который можно подключить к другим проектам-пакетам. Несколько пакетов объединяются в «гнездо» (nest), а гнезда — в коллекции (assemblies).
TheIDE размещает все созданные в нём программы в общее глобальное дерево пакетов. Корень дерева пакетов выбирается пользователем при первом запуске IDE, а все его программы будут хранится только в подкаталогах этого каталога.
Главным отличием от других библиотек аналогичного назначения является то, что все виджеты как правило создаются статически, как обычные переменные-члены класса (хотя сохраняется и возможность динамическое создания виджетов). Существуют особые типы полей ввода для вещественных и целых чисел. Например виджеты окна программы-калькулятора могут быть описаны так:
class MyWindow : public TopWindow {
public:
EditDouble val1, val2; // Поля ввода для операндов
Label l1,l2; // Подписи для полей ввода
DropList operation; // Выпадающий список операций
Label l3; // Подпись для списка
Button compute; // Кнопка «вычислить»
Label result; // Надпись для результата
Затем, при размещении виджетов вручную, мы должны расположить в окне программы с помощью функции
Add(widget)
(пример её использования см. в разделе
Hello World
).
На самом деле объекты поддержки виджетов существуют в динамической памяти, но они скрыты из области видимости и создаются и уничтожаются автоматически, мы оперируем только с их статическими «обёртками». Это позволяет избавится от ручного управления памятью, вы уже не сможете организовать утечку памяти , забыв написать delete . Хорошая практика программирования с Ultimate++ — никогда не использовать указатели для управления ресурсами. Для управления наборами данных переменного размера или полиморфного типа, используются контейнеры NTL. «Умных указателей» (типа boost ::shared_ptr ), в NTL нет, они не нужны и считаются плохой практикой. Такой подход к управлению памятью в C++ хорошо зарекомендовал себя, практически не уступая сборке мусора по удобству использования и превосходя её по производительности и детерминированности поведения программы.
Любой виджет в U++ имеет некое «естественное» значение. Так, для поля ввода значением будет введённый текст, для списка – выбранный элемент, для кнопки – функция-обработчик её нажатия. Для получения значения виджета служит оператор
~widget
(возвращает значение вариантного типа
Value
), а для установки – оператор
widget <<= значение
. Чтобы установить в качестве значения виджета, такого как кнопка, функцию обработчик, нужно «обернуть» имя соотв. функции-члена класса в макрос
THISBACK()
.
В большинстве GUI-библиотек, таких как Qt , каждый виджет хранит список указателей на своих потомков, т. е. иерархия виджетов является свойством экземпляров виджетов и не зависит от порядка их определения в теле класса. В Ultimate++ же иерархия определяется исключительно на уровне классов — каждый виджет-контейнер, содержащий другие виджеты определяется как класс, членами которого являются все вложенные виджеты.
Существует альтернатива ручному размещению виджетов в конструкторе окна — визуальный редактор компоновок (Layout Editor).
Компоновки
созданные в нём представляют собой корректные с точки зрения C++ include-файлы, использующие специальные макросы и имеющие расширение
.lay
. Для работы с компоновками мы должны подключить к нашему C++ файлу библиотеку заголовков lay.h, которая автоматически подключает файл-компоновки заданный c помощью директивы
#define LAYOUTFILE
.
#define LAYOUTFILE <demo/demo1.lay>
#include <CtrlCore.h>
Если компоновка называется, к примеру main , то для её подключения к классу главного окна программы надо объявить его как
class MyWindow : public Withmain<TopWindow> {
где Withmain — шаблонный класс, автоматически созданный макросами lay.h на основании lay-файла. Используется шаблона, а не простой класс или структура, благодаря чему как базовый класс вы можете использовать не только диалоговое окно ( TopWindow ) но и любой тип виджета.
Чтобы разместить виджеты окна согласно компоновке, в начало конструктора файла надо добавить вызов
CtrlLayout(*this);
Такой подход к визуальному редактированию интерфейса позволяет статически компилировать файлы компоновки, а не интерпретировать их во время работы программы, как это делают многие GUI инструменты, что ведёт к повышению быстродействия созданных в Ultimate++ приложений.
Однако, редактор компоновок не является полноценным визуальным редактором интерфейса, таким как QtDesigner или Glade . Он лишь позволяет задать имена и относительные положения виджетов одного уровня иерархии. Все свойства виджетов (кроме простейших, вроде надписи на кнопке) и логика их взаимодействия прописываются в коде программы.
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
GUI_APP_MAIN
{
}
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
class MyWindow : public TopWindow {
public:
MyWindow() {
Title("Hello world!");
MinimizeBox();
MaximizeBox();
Sizeable();
SetRect(0, 0, 300, 300);
}
};
GUI_APP_MAIN
{
MyWindow().Run();
}
В следующем примере создаётся (без использования визуального редактора) приложение с кнопкой «HelloWorld».
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
class MyApp : public TopWindow {
typedef MyApp CLASSNAME;
public:
MyApp() {
Title("Hello world");
button.SetLabel("Hello world!");
button <<= THISBACK(Click);
Add(button.HSizePos(100, 100).VSizePos(100, 100));
}
private:
void Click() {
if(PromptYesNo("Button was clicked. Do you want to quit?"))
Break();
}
Button button;
};
GUI_APP_MAIN
{
MyApp().Run();
}
В разделе официального сайта вы сможете найти примеры создания на U++ достаточно сложной формы и сравнить её с реализацией аналогичной функциональности на Qt , wxWidgets и Java / Swing .