Ultimativt++ | |
---|---|
| |
Type | Bibliotek med grænsefladeelementer (widgets) , IDE |
Udvikler | Mirek Fídler, Iñaki Zabala, Tomáš Rylek, Daniel Kos, Massimo Del Fedele, Zbigniew Rębacz + projektmedlemmer |
Skrevet i | C++ |
Operativ system | Cross platform |
nyeste version | 2022.2 (rev. 16270) ( 27. maj 2022 ) |
Licens | BSDL |
Internet side | ultimatepp.org |
Ultimate++ (også kendt som U++ og UPP ) er et softwareudviklingsværktøj på tværs af platforme i programmeringssproget C++ . Målet med U++ er at reducere kompleksiteten af typiske desktop-applikationer ved at gøre stor brug af C++-funktioner. Kører på Linux / X11 , BSD / X11 , Windows og siden version 2019.1 af MacOS X. Udviklingsstøtte til Android er under udvikling [1] .
Projektet har været under udvikling siden 1999 , kernen i Ultimate++-teamet består af tjekkiske programmører.
Det er en ramme, der ikke kun er designet til at give hurtig udvikling af GUI- applikationer, men også ideelt set til at erstatte alle tredjeparts biblioteker og værktøjer til C ++, inklusive endda STL (som i U ++ spilles af NTL-biblioteket - Nyt skabelonbibliotek). Ultimate++ ligner Qt på denne måde, selvom det går endnu længere i denne retning. UPP, i modsætning til Qt, udvider imidlertid ikke C++ med ikke-standardiserede kildemakroprocessorer, alle højniveauværktøjerne i denne ramme, som ligner udvidelser af C++ sproget, implementeres gennem standardmekanismer som skabelonmetaprogrammering og makroer . Dette gør det muligt at bruge skabelonmekanismen ved oprettelse af en grænseflade, hvilket gør det muligt at opnå kompakt og letlæselig kode. Hvad angår kortfattethed, ligner kode skrevet ved hjælp af U++ moderne " superniveau " scriptsprog .
Ultimate++ inkluderer følgende biblioteker:
Alle disse komponenter er designet til at blive brugt sammen og er ikke designet til at fungere individuelt. Ultimate++ bruger en specifik kodeorganisation i form af såkaldte "pakker", så udvikling med Ultimate++, men uden brug af TheIDE er usandsynlig[ afklare ] muligt i praksis.
Kildekode i U++ forekommer i kategorier af pakker (en idé, der er kendt for Delphi- eller Lazarus -udviklere ), snarere end forskellige biblioteker og kildefiler. Teknisk set er en pakke blot en separat mappe, der indeholder kildekoderne, som også indeholder en beskrivelsesfil med en upp-udvidelse. .upp-filer opdateres automatisk af IDE og ligner lave filer med beskrivelser af afhængigheder og kompileringsflag.
Når du inkluderer en pakke i et projekt, vil IDE automatisk indstille de nødvendige stier og flag til compileren. Selve projektet er også en pakke, der kan kobles til andre pakkeprojekter. Flere pakker kombineres til en "rede" (rede), og reder kombineres til samlinger (samlinger).
TheIDE placerer alle programmer, der er oprettet i det, i et fælles globalt pakketræ. Roden af pakketræet vælges af brugeren, når IDE først startes, og alle dens programmer vil kun blive gemt i undermapper til denne mappe.
Den største forskel fra andre biblioteker med lignende formål er, at alle widgets normalt oprettes statisk, ligesom almindelige klassemedlemsvariabler (selvom evnen til at oprette widgets dynamisk også bevares). Der er specielle typer indtastningsfelter for reelle tal og heltal. For eksempel kan lommeregnervindue-widgets beskrives som følger:
klasse MyWindow : public TopWindow { offentligt : EditDouble val1 , val2 ; // Indtastningsfelter for operander Label l1 , l2 ; // Etiketter til inputfelter DropList operation ; // Dropdown liste over operationer Label l3 ; // Label for listen Button compute ; // Beregn knap Etiket resultat ; // Mærk til resultatetSå, når vi placerer widgets manuelt, skal vi placere dem i programvinduet ved hjælp af en funktion Add(widget)(se Hello World- sektionen for et eksempel på dets brug ).
Faktisk eksisterer widget-understøttelsesobjekter i dynamisk hukommelse, men de er skjult fra omfanget og oprettes og ødelægges automatisk, vi opererer kun med deres statiske "indpakninger". Dette giver dig mulighed for at slippe af med manuel hukommelseshåndtering, du kan ikke længere organisere en hukommelseslækage ved at glemme at skrive delete . Det er en god praksis at programmere med Ultimate++ for aldrig at bruge pointere til at administrere ressourcer. For at administrere datasæt af variabel størrelse eller polymorf type, bruges NTL-containere. Der er ingen "smarte pointers" (som boost ::shared_ptr ) i NTL, de er ikke nødvendige og betragtes som dårlig praksis. Denne tilgang til hukommelsesstyring i C++ har bevist sig selv godt, praktisk talt lig med affaldsopsamling med hensyn til brugervenlighed og overgå den med hensyn til ydeevne og deterministisk opførsel af programmet.
Hver widget i U++ har en "naturlig" betydning. Så for inputfeltet vil værdien være den indtastede tekst, for listen - det valgte element, for knappen - funktionshandleren til at trykke på den. ~widget- operatoren (returnerer en værdi af varianttypen Value) bruges til at få værdien af en widget, og widget-værdioperatoren <<= bruges til at indstille den . For at indstille værdien af en widget, såsom en knap, til en handlerfunktion, skal du "ombryde" navnet hhv. klassemedlemsfunktion til en makro THISBACK().
I de fleste GUI-biblioteker, såsom Qt , holder hver widget en liste over pointere til sine børn, dvs. widgethierarkiet er en egenskab for widgetforekomster og afhænger ikke af den rækkefølge, de er defineret i i klassens krop. I Ultimate++ er hierarkiet dog udelukkende defineret på klasseniveau - hver container-widget, der indeholder andre widgets, er defineret som en klasse, som alle indlejrede widgets er medlemmer af.
Der er et alternativ til manuelt at placere widgets i vindueskonstruktøren - den visuelle layout-editor (Layout Editor). Layouterne , der er oprettet i den, er C++-korrekte inkluderer filer, der bruger specielle makroer og har filtypenavnet .lay . For at arbejde med layouts skal vi inkludere lay.h header-biblioteket i vores C++-fil, som automatisk inkluderer den layout-fil, der er angivet ved hjælp af #define LAYOUTFILE.
#define LAYOUTFIL <demo/demo1.lay> #include <CtrlCore.h>Hvis layoutet for eksempel hedder main , skal du for at forbinde det til klassen i hovedprogramvinduet erklære det som
klasse MyWindow : public Withmain < TopWindow > {hvor Withmain er en skabelonklasse, der automatisk genereres af lay.h-makroerne baseret på lay-filen. Den bruger en skabelon i stedet for en simpel klasse eller struktur, så du kan bruge enhver type widget som basisklasse, ikke kun en dialogboks ( TopWindow ).
For at arrangere vindueswidgets i henhold til layoutet skal du i begyndelsen af filkonstruktøren tilføje et opkald
CtrlLayout ( * dette );Denne tilgang til visuel grænsefladeredigering gør det muligt statisk at kompilere linkfiler i stedet for at fortolke dem under kørsel, som mange GUI-værktøjer gør, hvilket fører til øget ydeevne af applikationer oprettet i Ultimate++.
Layouteditoren er dog ikke en komplet visuel grænsefladeeditor som QtDesigner eller Glade . Det giver dig kun mulighed for at angive navne og relative positioner for widgets på samme niveau af hierarki. Alle egenskaber for widgets (undtagen de enkleste, som inskriptionen på en knap) og logikken i deres interaktion er skrevet i programkoden.
Følgende eksempel opretter (uden at bruge den visuelle editor) en applikation med en "HelloWorld"-knap.
#include <CtrlLib/CtrlLib.h> bruger navneområde Upp ; klasse MyApp : public TopWindow { typedef MyApp KLASSENAVN ; offentligt : MyApp () { titel ( "hej verden" ); knap . SetLabel ( "Hej verden!" ); knap <<= TILBAGE ( Klik ); Tilføj ( knap . HSizePos ( 100 , 100 ). VSizePos ( 100 , 100 )); } privat : void Klik () { if ( SpørgJaNej ( "Der blev klikket på knappen. Vil du afslutte?" )) bryde (); } Knap knap ; }; GUI_APP_MAIN { minApp (). køre (); }I afsnittet Sammenligninger på det officielle websted kan du finde eksempler på at skabe en ret kompleks form i U++ og sammenligne den med implementeringen af lignende funktionalitet i Qt , wxWidgets og Java / Swing .
IDE | |
---|---|
Universel | |
C / C++ | |
GRUNDLÆGGENDE | |
Java |
|
Pascal | |
PHP |
|
Python | |
ActionScript | |
rubin | |
sammenligning |
af GUI-elementer | Værktøjssæt (sæt)|||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
lavt niveau |
| ||||||||||||||||||||||||||
højt niveau |
|