Ultima ++

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 5 octombrie 2020; verificările necesită 8 modificări .
Ultima ++

U++ TheIDE snapshot (editor de aspect selectat)
Tip de Biblioteca de elemente de interfață (widgeturi) , IDE
Dezvoltator Mirek Fídler, Iñaki Zabala, Tomáš Rylek, Daniel Kos, Massimo Del Fedele, Zbigniew Rębacz + membri ai proiectului
Scris in C++
Sistem de operare Platformă transversală
ultima versiune 2022.2 (rev. 16270) ( 27 mai 2022 )
Licență BSDL
Site-ul web ultimatepp.org

Ultimate++ (cunoscut și ca U++ și UPP ) este un set de instrumente de dezvoltare software multiplatformă în limbajul de programare C++ . Scopul U++ este de a reduce complexitatea aplicațiilor desktop tipice prin utilizarea intensă a caracteristicilor C++. Rulează pe Linux / X11 , BSD / X11 , Windows și începând cu versiunea 2019.1 a MacOS X. Suportul de dezvoltare pentru Android este în curs de dezvoltare [1] .

Proiectul se dezvoltă din 1999 , nucleul echipei Ultimate++ este alcătuit din programatori cehi .

Caracteristici

Compoziția și scopul cadrului

Este un cadru conceput nu numai pentru a oferi o dezvoltare rapidă a aplicațiilor GUI , ci și, în mod ideal, pentru a înlocui toate bibliotecile și instrumentele terțe pentru C ++, inclusiv chiar STL (care în U ++ este redat de biblioteca NTL - Bibliotecă nouă de șabloane). Ultimate++ este similar cu Qt în acest fel, deși merge și mai departe în această direcție. Cu toate acestea, UPP, spre deosebire de Qt, nu extinde C++ cu procesoare macro sursă non-standard, toate instrumentele de nivel înalt ale acestui cadru, care arată ca extensii ale limbajului C++, sunt implementate prin mecanisme standard precum metaprogramarea șablonului și macro -uri . Acest lucru face posibilă utilizarea mecanismului șablon atunci când se creează o interfață, ceea ce face posibilă obținerea unui cod compact și ușor de citit. În ceea ce privește concizia, codul scris folosind U++ seamănă cu limbajele moderne de scriptingsuper-nivel ” .

Ultimate++ include următoarele biblioteci:

Toate aceste componente sunt concepute pentru a fi utilizate împreună și nu sunt concepute pentru a funcționa individual. Ultimate++ folosește o organizare specifică de cod sub formă de așa-numite „pachete”, astfel încât dezvoltarea cu Ultimate++, dar fără utilizarea TheIDE este puțin probabilă[ clarifica ] posibil în practică.

Organizarea surselor

Codul sursă în U++ apare în categorii de pachete (o idee familiară dezvoltatorilor Delphi sau Lazarus ), mai degrabă decât în ​​biblioteci și fișiere sursă disparate. Din punct de vedere tehnic, un pachet este doar un director separat care conține codurile sursă, care conține și un fișier de descriere cu extensia upp. Fișierele .upp sunt actualizate automat de către IDE și sunt similare cu fișierele cu descrieri ale dependențelor și steaguri de compilare.

Când includeți un pachet într-un proiect, IDE-ul va seta automat căile și steagurile necesare pentru compilator. Proiectul în sine este, de asemenea, un pachet care poate fi conectat la alte proiecte de pachete. Mai multe pachete sunt combinate într-un „cuib” (cuib), iar cuiburile sunt combinate în colecții (ansambluri).

TheIDE plasează toate programele create în el într-un arbore global comun de pachete. Rădăcina arborelui pachetului este selectată de utilizator la prima lansare a IDE-ului, iar toate programele sale vor fi stocate doar în subdirectoarele acestui director.

Caracteristici de lucru cu widget -uri

Principala diferență față de alte biblioteci cu un scop similar este că toate widget-urile sunt de obicei create static, ca variabilele obișnuite ale membrilor clasei (deși capacitatea de a crea widget-uri în mod dinamic este, de asemenea, păstrată). Există tipuri speciale de câmpuri de intrare pentru numere reale și întregi. De exemplu, widget-urile ferestrei calculatorului pot fi descrise după cum urmează:

clasa MyWindow : public TopWindow { public : Editare dublu val1 , val2 ; // Câmpuri de intrare pentru operanzi Etichetă l1 , l2 ; // Etichete pentru câmpurile de intrare Operație DropList ; // Lista derulantă a operațiunilor Eticheta l3 ; // Etichetă pentru listă Buton compute ; // Calculează butonul Etichetă rezultat ; // Etichetă pentru rezultat

Apoi, atunci când plasăm manual widget-uri, trebuie să le poziționăm în fereastra programului folosind o funcție Add(widget)(vezi secțiunea Hello World pentru un exemplu de utilizare a acestuia ).

De fapt, obiectele suport widget există în memoria dinamică, dar sunt ascunse din sfera de aplicare și sunt create și distruse automat, operăm doar cu „wrapper-urile” lor statice. Acest lucru vă permite să scăpați de gestionarea manuală a memoriei, nu mai puteți organiza o scurgere de memorie uitând să scrieți ștergere . Este o practică bună să programați cu Ultimate++ pentru a nu folosi niciodată pointeri pentru a gestiona resursele. Pentru a gestiona seturi de date de dimensiune variabilă sau de tip polimorf, se folosesc containere NTL. Nu există „indicatoare inteligente” (cum ar fi boost ::shared_ptr ) în NTL, nu sunt necesare și sunt considerate o practică proastă. Această abordare a managementului memoriei în C++ s-a dovedit bine, practic egalând colectarea gunoiului din punct de vedere al utilizabilității și depășind-o în ceea ce privește performanța și comportamentul determinist al programului.

Fiecare widget din U++ are o semnificație „naturală”. Deci, pentru câmpul de introducere, valoarea va fi textul introdus, pentru listă - elementul selectat, pentru buton - manevrătorul de funcție pentru apăsarea acestuia. Operatorul ~widget (returnează o valoare de tipul variantei Value) este folosit pentru a obține valoarea unui widget, iar operatorul widget <<= value este folosit pentru a-l seta . Pentru a seta valoarea unui widget, cum ar fi un buton, la o funcție de gestionare, trebuie să „împachetați” numele resp. funcția membru al clasei într-o macrocomandă THISBACK().

În majoritatea bibliotecilor GUI, cum ar fi Qt , fiecare widget păstrează o listă de pointeri către copiii săi, adică ierarhia widget-ului este o proprietate a instanțelor widget și nu depinde de ordinea în care sunt definite în corpul clasei. În Ultimate++, totuși, ierarhia este definită numai la nivel de clasă - fiecare widget container care conține alte widget-uri este definit ca o clasă, din care toate widget-urile imbricate sunt membri.

Folosind Editorul de aspect

Există o alternativă la plasarea manuală a widget-urilor în constructorul ferestrei - editorul de aspect vizual (Layout Editor). Aspectele create în acesta sunt corecte în C++, includ fișiere care folosesc macrocomenzi speciale și au extensia .lay . Pentru a lucra cu machete, trebuie să includem biblioteca de antet lay.h în fișierul nostru C++, care include automat fișierul de aspect specificat folosind #define LAYOUTFILE.

#define LAYOUTFILE <demo/demo1.lay> #include <CtrlCore.h>

Dacă aspectul este numit, de exemplu , main , atunci pentru a-l conecta la clasa ferestrei principale a programului, trebuie să îl declarați ca

class MyWindow : public Withmain < TopWindow > {

unde Withmain este o clasă șablon generată automat de macrocomenzile lay.h bazate pe fișierul lay. Folosește un șablon mai degrabă decât o simplă clasă sau struct, astfel încât să puteți utiliza orice tip de widget ca clasă de bază, nu doar o casetă de dialog ( TopWindow ).

Pentru a aranja widget-urile ferestrei în funcție de aspect, la începutul constructorului de fișiere, trebuie să adăugați un apel

CtrlLayout ( * aceasta );

Această abordare a editării interfeței vizuale face posibilă compilarea statică a fișierelor link, mai degrabă decât interpretarea lor în timpul execuției, așa cum fac multe instrumente GUI, ceea ce duce la creșterea performanței aplicațiilor create în Ultimate++.

Cu toate acestea, editorul de aspect nu este un editor de interfață vizuală complet precum QtDesigner sau Glade . Vă permite doar să setați numele și pozițiile relative ale widget-urilor de același nivel de ierarhie. Toate proprietățile widget-urilor (cu excepția celor mai simple, cum ar fi inscripția pe un buton) și logica interacțiunii lor sunt scrise în codul programului.

Exemple

Aplicație minimă

#include <CtrlLib/CtrlLib.h> folosind spațiul de nume Upp ; GUI_APP_MAIN { }

Crearea unei ferestre

#include <CtrlLib/CtrlLib.h> folosind spațiul de nume Upp ; clasa MyWindow : public TopWindow { public : MyWindow () { titlu ( "Bună lume!" ); MinimizeBox (); MaximizeBox (); Dimensiune (); SetRect ( 0 , 0 , 300 , 300 ); } }; GUI_APP_MAIN { MyWindow (). alerga (); }

salut lumea

Următorul exemplu creează (fără a utiliza editorul vizual) o aplicație cu un buton „HelloWorld”.

#include <CtrlLib/CtrlLib.h> folosind spațiul de nume Upp ; clasa MyApp : public TopWindow { typedef MyApp CLASSNAME ; public : Aplicația mea () { titlu ( "bună lume" ); butonul . SetLabel ( "Bună lume!" ); butonul <<= THISBACK ( Click ); Adăugați ( buton . HSizePos ( 100 , 100 ). VSizePos ( 100 , 100 )); } privat : void Faceți clic pe () { if ( PromptYesNo ( "Butonul a fost apăsat. Doriți să renunțați?" )) pauză (); } Buton buton ; }; GUI_APP_MAIN { myApp (). alerga (); }

Un exemplu mai complex

În secțiunea Comparații a site-ului oficial, puteți găsi exemple de creare a unei forme destul de complexe în U++ și o comparați cu implementarea unei funcționalități similare în Qt , wxWidgets și Java / Swing .

Note

  1. Lucrul cu Android Builder . Preluat la 22 decembrie 2019. Arhivat din original la 22 decembrie 2019.

Link -uri