Používateľské rozhranie je v nórčine, prípadne píšeme v QT. Získanie atribútov súboru v Qt

Dobrý deň, milí čitatelia! Pomerne nedávno som dokončil vývoj jednej z mojich aplikácií v Qt a chcel som vytvoriť odborný program inštalácie, aby bolo všetko „ako u dospelých“. Ako sa ukázalo, nie je to ľahké, pretože na oficiálnej webovej stránke súpravy nástrojov nie sú takmer žiadne informácie o nasadení. Tento článok pojednáva o niektorých fázach prípravy programov na Qt verzie 5.2 alebo vyššej na distribúciu do počítačov iných používateľov. Takže tu je plán sprievodcu:
  1. Príprava projektu Qt na nasadenie
  2. Rozloženie súpravy na distribúciu programu
  3. Podpisovanie kódu a vytvorenie inštalátora
Nestrácajme čas a pustme sa do práce.

1. Príprava projektu Qt na nasadenie

Na uľahčenie dodržiavania pokynov vytvoríme jednoduchý projekt Qt Widgets. Všetky nasledujúce operácie sa budú týkať tohto projektu. Nižšie je uvedený obsah zdrojových súborov aplikácie:

HelloWorld.pro

QT += základné widgety gui CIEĽ = ŠABLONA HelloWorld = ZDROJE aplikácie += main.cpp


main.cpp

#include #include int main(int argc, char *argv) ( QApplication a(argc, argv); QLabel label("Ahoj, svet!"); label.setAlignment(Qt::AlignCenter); label.resize(200, 50); label .show(); návrat a.exec();


Programy vyzerajú obzvlášť kvalitne a profesionálne, ak nesú metadáta o vývojárovi, verzii softvérový produkt, autorské práva, jazyk a oveľa viac. Pozrime sa napríklad na vlastnosti súboru Photoshop.exe: známy systém Adobe Photoshop. Obrázok nižšie zobrazuje okno vlastností tohto súboru:

Takéto informácie môžete pridať pomocou zdrojový súbor. Zdrojový súbor má príponu .rc a nesie v sebe textový kód, ktorý popisuje zdroje použité v aplikácii. Podobné skripty sa používajú v projektoch Vizuálne štúdio, založené na WinAPI a obsahujú rôzne deskriptory pre ikony, reťazce, identifikátory a ďalšie veci. V projektoch Qt to nedáva zmysel, ale aj tak je potrebné zahrnúť všeobecné informácie o programe. Nižšie je uvedený zdrojový kód zdrojového súboru a obsah súboru projektu, ktorý bude tiež potrebné upraviť:

zdroje.rc

IKONA IDI_ICON1 "icon.ico" #include #define VER_FILEVERSION 1,0,0,0 #define VER_FILEVERSION_STR "1.0.0.0\0" #define VER_PRODUCTVERSION 1,0,0 #define VER_PRODUCTVERSION_STR "1.0.0" #define VER_FILEDESCRIPTION_STR "HelloWorld"_STR "HelloWorld"_STR "Ahoj SVET " #define VER_LEGALCOPYRIGHT_STR "Autorské práva (C) 2015, MojaSpoločnosť" #define VER_ORIGINALFILENAME_STR "HelloWorld.exe" #define VER_PRODUCTNAME_STR " Ahoj svet" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_PRODUCTVERSION BEGIN BLOK "StringFileInfo" BEGIN BLOK "040904E4" BEGIN VALUE "FileDescription", VER_FILEDESCRIPTION_STR VALUE "FileVersion", VER_FILEVERSION_STR VALUE "Interný názov", VER_INTERNALNAME_STR VALUE "Zákonné Autorské práva", VER_LEGALCOPYRIGHT_STR VALUE "Pôvodný názov súboru", VER_ORIGINALFILENAME_STR VALUE "Meno Produktu", VER_PRODUCTNAME_STR VALUE "Verzia produktu", VER_PRODUCTVERSION_STR END END BLOCK "VarFileInfo" BEGIN VALUE "Preklad", 0x409, 1252 END END !}


HelloWorld.pro

QT += widgety hlavného grafického rozhrania TARGET = HelloWorld TEMPLATE = ZDROJE aplikácie += main.cpp RC_FILE = resources.rc


V tomto príklade je dôležité nezabudnúť pridať súbory zdroje.rc A icon.ico do priečinka s zdrojové súbory projektu. Obrázok nižšie zobrazuje okno vlastností programu po zostavení:

Niekedy je potrebné, aby bol program spustený s právami správcu. V rámci Qt to možno dosiahnuť pomocou jednoduchých inštrukcií v súbore projektu. Nižšie je uvedený kód, ktorý umožňuje programu požiadať o administrátorské práva pri spustení:

HelloWorld.pro

QT += widgety core gui TARGET = HelloWorld TEMPLATE = app SOURCES += main.cpp RC_FILE = resources.rc win32 ( CONFIG += embed_manifest_exe QMAKE_LFLAGS_WINDOWS += /MANIFESTUAC:"level="requireAdministrator"" )


Treba poznamenať, že všetky vyššie uvedené pokyny budú zaručene fungovať iba pri použití súpravy Visual Studio Build Kit. Detailné informácie o zdrojových súboroch nájdete na portáli MSDN pod .

2. Usporiadanie súpravy na distribúciu programu

Vytvorenie distribúcie aplikácie vrátane všetkých súborov, ktoré je potrebné nainštalovať na počítače používateľov, je asi najťažšia časť nasadenia. Musíte starostlivo analyzovať spustiteľný súbor programu na závislosti, postarať sa o prekladové súbory a nezabudnúť na prostriedky aplikácie. Pomôcka pomôže vyriešiť niektoré z týchto problémov windeployqt.exe , ktorý sa dodáva s montážnou sadou. Tento nástroj beží na príkazovom riadku a podporuje niektoré možnosti konfigurácie. Obrázok nižšie zobrazuje okno príkazového riadka so spusteným nástrojom:

Posledný parameter musí špecifikovať cestu k binárnym súborom zostavenej aplikácie alebo názvy týchto súborov. V tabuľke nižšie sú uvedené parametre pomôcky, ktoré môžete použiť pri práci s ňou:

Parameter Popis
-?, -h, --pomoc Výstup pomoci
-v, --verzia Zobrazenie informácií o verzii
--r<katalóg> Použite zadaný adresár namiesto adresára súborov
--libdir<cesta> Adresár, do ktorého sa skopírujú knižnice
--debug Použite ladiace verzie súborov
-- uvoľnenie Na uvoľnenie použite súbory
--release-with-debug-info Použite súbory vydania s informáciami o ladení
-- sila Nahradiť existujúce súbory
--suchý chod Vykonajte prácu na overenie
--žiadne pluginy Preskočiť kopírovanie doplnkov
--žiadne knižnice Preskočiť kopírovanie knižníc
--qmldir<katalóg> Skenovanie importu QML od zadaného adresára
--žiadny-rýchly-import Preskočiť Qt Quick
--bez prekladov Preskočiť kopírovanie prekladových súborov
--no-system-d3d-compiler Preskočte kopírovanie kompilátora Direct3D
--compiler-runtime Kopírovať závislosti kompilátora
--no-compiler-runtime Preskočiť závislosti kompilátora
--webkit2 Skopírujte súbory WebKit2
--no-webkit2 Preskočiť WebKit2
--json Tlačový výstup vo formáte JSON
--uhol Skopírujte súbory ANGLE
--bez uhla Preskočiť ANGLE
--zoznam<režim> Vytlačte iba názvy skopírovaných súborov. Režimy: zdroj, cieľ, príbuzný, mapovanie
--verbózny<úrovni> Úroveň ladenia
-<názov knižnice> Pridajte špecifikovanú knižnicu
--nie-<názov knižnice> Nepridávajte špecifikovanú knižnicu

Po spustení pomôcky by sa v blízkosti spustiteľného súboru programu mali objaviť rôzne knižnice a servisné súbory, ktoré umožnia spustenie a správne fungovanie aplikácie na mnohých počítačoch. Obrázok nižšie zobrazuje okno Prieskumník systému Windows s distribučnou štruktúrou:

Treba poznamenať, že pred použitím windeployqt.exe musíte pridať cestu k tomuto súboru premenná prostredia PATH, inak tento nástroj nebude fungovať.

3. Podpisovanie kódu a vytvorenie inštalátora

Po zostavení súpravy na distribúciu programu skúsme spustiť aplikáciu ako správca. Obrázok nižšie zobrazuje správu systémová služba Užívateľský účet ovládanie (UAC) s upozornením na spustenie aplikácie od neznámeho vydavateľa:

Toto varovanie odrádza používateľov a dodáva aplikácii zlú povesť. Ak chcete napraviť situáciu, musíte podpísať súbory programu pomocou špeciálneho certifikátu. Zdá sa, že vývojári podpísaním svojich programov poskytujú dodatočné záruky spoľahlivosti aplikácií informačná bezpečnosť. Vývojári open source softvéru môžu získať certifikáty pre svoje projekty zadarmo napríklad na stránke Certum. Na použitie certifikátu budete potrebovať špeciálny program, ktorý podpíše súbory aplikácie. Na to môžete použiť šikovný nástroj Certifikačná pomôcka DigiCert. Obrázok nižšie zobrazuje okno tohto programu so zoznamom certifikátov na podpisovanie kódu:

Po použití tohto nástroja by ste sa mali pokúsiť spustiť aplikáciu znova ako správca. Nižšie je správa UAC s informáciami o vydavateľovi programu:

Po dokončení práce je čas premýšľať o výbere systému na vytvorenie inštalátora pre pripravenú aplikáciu. Existujú platené aj bezplatné platených produktov dokončiť túto úlohu. V tabuľke nižšie sú uvedené niektoré nástroje na vytváranie inštalátorov:

Je ťažké poskytnúť akékoľvek odporúčania týkajúce sa výberu jedného alebo druhého systému. Vývojári open source softvéru si pravdepodobne vyberú bezplatné nástroje, pričom platené produkty často využívajú komerčné spoločnosti.

Záver

Na záver treba povedať, že k príprave žiadostí o uvoľnenie by sa malo pristupovať s veľkou zodpovednosťou. Pred použitím programu používateľ prejde fázou inštalácie produktu do počítača. Informácie, ktoré dostane, by mali urobiť priaznivý dojem.

Každá seriózna aplikácia GUI (a iné) používa zdrojové súbory. V tomto prípade máte dve možnosti: buď pripojiť prostriedky pozdĺž relatívnych ciest súborového systému, alebo ich umiestniť priamo do binárneho súboru alebo knižnice aplikácie. Každý z týchto prístupov má svoje výhody a nevýhody.

V prvom prípade (zdroje - externé súbory) sa aplikácia stáva flexibilnejšou, pretože zdroje možno meniť bez prestavby, používatelia však môžu náhodne (alebo úmyselne) poškodiť niektoré zdroje, čím narušia správnu činnosť aplikácie. Navyše, ak relatívne cesty aplikácie zlyhajú, zdrojové súbory sa nenájdu.

So zabudovanými zdrojmi binárny súbor, situácia je presne opačná: aplikácia sa stáva monolitickou, spustiteľný súbor má veľká veľkosť, akákoľvek zmena si vyžaduje opätovnú montáž, ale náhodne narušiť jej funkčnosť (napríklad výmenou obrázka) sa stáva takmer nemožné.

S prihliadnutím na všetky pre a proti posledná možnosť vo väčšine prípadov sa uprednostňuje. To si povieme.

Reklama

Vytvorenie súboru s popisom prostriedkov

Najprv vytvorte súbor s popisom zdrojov, ktoré budete používať. Vyzerá to takto (nazvime to res.qrc):

logo.png

Vo vyššie uvedenom príklade sme definovali jednu predponu: /images. Možno ho považovať za logický adresár zdrojov. Takýchto prefixov môže byť ľubovoľný počet. Ak má vaša aplikácia napríklad zvukové efekty, môžete pridať predponu /sounds. Ak chcete vytvoriť hlbšiu hierarchiu, použite predpony ako /some/long/prefix .

Otagovať vnorené sú definície súborov súvisiace s príslušnou predponou. Príklad obsahuje jeden obrázok, logo.png , ale môžete zadať toľko súborov, koľko potrebujete. Použite relatívne cesty k súborom, pričom referenčný adresár berte ako ten, v ktorom sa nachádza súbor qrc.

Má zmysel explicitne alokovať zdroje do podadresárov systém súborov projektu. Napríklad umiestnite obrázok logo.png do obrázkov/ . Potom má záznam podobu:

images/logo.png

V tomto prípade logická cesta k súboru logo.png opäť vyzerá takto: /images/logo.png.

Kvôli stručnosti môžete použiť aliasy takto:

dlhá/relatívna/cesta/k/logu.png

Súbor je dostupný na logickej ceste /myprefix/logo.png.

Potom musíte prepojiť dokončený súbor qrc s projektom. Ak to chcete urobiť, pridajte do svojho súboru profík takýto riadok:

ZDROJE += res.qrc

Vo vyššie uvedenom príklade je súbor qrc umiestnený na rovnakej úrovni ako súbor pro. Ak použijete viac zložitý obvod umiestnenie súborov, potom použite relatívnu cestu.

Upozorňujeme, že QtCreator poskytuje pomerne pohodlné rozhranie GUI na prácu so zdrojovými súbormi. Ak chcete vytvoriť nový súbor qrc, kliknite na obsahové menu pre požadovaný projekt do položky Pridať nový.... V zobrazenom dialógovom okne prejdite do skupiny Qt a vyberte položku Qt Resource file. Po úspešnom vytvorení súboru prostriedkov sa na paneli Projekt vedľa Hlavičky a zdroje zobrazí nová skupina Zdroje. Otvorením súboru qrc sa dostanete do editora zdrojov, ktorý vám celkom intuitívne umožňuje vykonávať rovnaké akcie, ktoré sme vykonali manuálne.

Reklama

Používanie zdrojov v aplikácii

Súbor qrc je teda pripravený a pripojený k projektu. Ostáva už len využiť výhody jeho používania. A urobiť to nie je vôbec ťažké:

#include #include int main(int argc, char* argv) ( QApplication a(argc, argv); QLabel lbl; QPixmap pix(":/images/logo.png"); lbl.setPixmap(pix); lbl.resize(pix.size ()); lbl.show();

Kľúčom je, ako získať prístup k obrázku (alebo akémukoľvek inému súboru) zo zdrojov. Cesta je zostavená nasledovne: najprv sa umiestni dvojbodka: , potom predpona /images, ktorú sme si sami zvolili, a nakoniec cesta k súboru (alebo aliasu) logo.png. Inak je všetko rovnaké ako pri práci s bežnými súbormi len na čítanie.

Záver

Používanie zdrojových súborov v projektoch Qt je veľmi jednoduché, takže ak potrebujete do aplikácie pridať obrázky, hudbu alebo čokoľvek iné, teraz viete, čo máte robiť.

V tomto článku budem hovoriť o vývoji používateľské rozhrania pomocou knižnice QT urobíme to isté pre vás krátka exkurzia do histórie Trolltech a na malom príklade zvážte vlastnosti vývoja na QT pre Mac OS X.

Ako to všetko začalo...

Nórsku spoločnosť Trolltech zaregistrovali v roku 1994 dvaja nórski chalani - Haavard North a Eirik Chambe-Eng. Spočiatku sa spoločnosť volala Quasar Technologies, ale neskôr bola premenovaná na Trolltech.

V rámci svojej práce sa Haavard podieľal na vývoji objektovo orientovaného systému na zobrazovanie informácií z ultrazvukového prístroja. Keďže boli priatelia od univerzity, chlapci vážne premýšľali o svojom vlastnom startupe. Snívali o vývoji najlepšej vývojovej knižnice C++ grafické rozhrania pre operačné systémy Unix.

V roku 1991 táto práca znamenala začiatok éry QT. V roku 1992 prišiel Eirik s jednou zo základných paradigiem QT - systémom signál/slot, Haavard túto myšlienku okamžite implementoval. Takto QT získalo svoj vlastný preprocesor kódu C++ – moc. A do konca roku 1993 bolo vykresľovacie jadro hotové a ďalší rok bola vydaná prvá verzia QT!

Vyvinuté - vyvinuté, ale predaj vášho produktu sa ukázal ako problematický. Nebolo východiska, bolo treba hľadať klientov, pretože pre mocných nórskych Vikingov bolo neslušné sedieť na krku svojich manželiek. S pomocou starých priateľov sa nám podarilo uzavrieť zmluvu s nórskou spoločnosťou Metis na vývoj grafického rozhrania na QT.

Veci nabrali na obrátkach a v roku 1996 sa aj Európska vesmírna agentúra stala klientmi Trolltech. Našlo sa samotné QT podpora Windows a dosiahol verziu 1.0! Trolltech začal rásť a najal ďalších dvoch vývojárov. Štart bol za nami, chalani pevne stáli na nohách a pred nami boli dobré vyhliadky.

V roku 1997 sa Matthias Ettrich, budúci otec KDE, rozhodol vytvoriť grafický shell pre Linux pomocou QT. S vydaním prvej verzie KDE bolo jasné, že QT sa stáva de facto štandardom pre vývoj grafických rozhraní pre Linux.

V roku 1999 bol vydaný QT 2, v roku 2001 sa objavil QT 3 V júni 2005 došlo k historickej udalosti - bola vydaná QT 4, výrazne vylepšená verzia rámca. V systéme Windows sa objavuje aj verzia knižnice GPL, QT sa stáva štandardom pre vývoj naprieč platformami. Od verzie 4 sa QT stalo plnohodnotným rámcom. Má všetko, čo by ste mohli chcieť: I/O zariadenia, kontajnery a algoritmy, podporu RPC cez D-Bus a oveľa viac.

Odvtedy prešlo pod mostom veľa vody... Trolltech sa rozrástol na veľkosť 250 ľudí a otvoril kancelárie po celom svete. V roku 2006 spoločnosť uskutočnila IPO. V januári 2008 Trolltech oznámil, že im Nokia dala ponuku, ktorá sa nedá odmietnuť. Obchod mal hodnotu 104 miliónov eur a Trolltech sa stal majetkom Nokie. Pýtate sa, prečo Nokia potrebovala trollov? Všetko je veľmi jednoduché! QT nie je ani zďaleka jediným produktom Trolltech. V roku 2004 bol vydaný produkt QTopia. QTopia nie je nič menej ako platforma pre mobilné zariadenia, založený na Embeded Linux a QT. Nokia zrejme vidí QTopia ako náhradu za súčasnú platformu Maemo a v budúcnosti možno aj Symbian.

To, čo odlišuje Trolltech, je ich obchodný model. QT je k dispozícii pod dvoma licenciami: GPL a proprietárna. Buď si teda kúpite licenciu QT a prispejete do pokladnice vývoja Trollltech a QT v rubľoch, alebo napíšete a otvoríte zdrojové kódy vašej aplikácie, čo prispieva k rozvoju Open Source a najmä QT.

Stručný prehľad schopností QT

Takže. Na vývoj aplikácií používateľského rozhrania v systéme Mac OS X je k dispozícii niekoľko rámcov:
  • Kakao. Tento rámec je dedičstvom mocného počítača Next Computer, ktorý Apple nepoužil. Tento rámec bol napísaný v Objective C a v súčasnosti presne toto je jediným strategickým cieľom spoločnosti Apple.
  • Uhlík. Apple sa postaral aj o vývojárov C++, a preto vytvoril Carbon. Časy Carbonu sú však érou Mac OS Classic v Mac OS X sa mení na zbytočný rudiment, ktorý sa skôr či neskôr možno aj stane Snežný leopard, bude zrušený. Uhlík existoval na uľahčenie prenosu aplikácie tretích strán z Mac OS 9 na Mac OS X. Najmä ak chcete, aby bola vaša aplikácia 64-bitová a schopná adresovať až 64 GB virtuálna pamäť, potom Carbon nie je pre vás. Adobe sa na tom už popálilo.
  • Rámce tretích strán. Je ich tiež obrovské množstvo, napríklad WxWidgets, GTK, TCL, ale v tomto článku porozprávame sa o QT :)
Teraz je QT pekné mocný nástroj, čo značne rozširuje možnosti C++. Ďalej o licenciách: komerčná verzia QT obsahuje ovládače pre RDBS typ DB2 atď.

Za zmienku stojí, že záujmy QT a Mac OS X sa pretínali na engine KHTML. KHTML – vykresľovacie jadro HTML stránky z projektu KDE, ktorý si Apple svojho času vybral ako základ pre svoj projekt WebKit, z ktorého sa neskôr zrodil Safari, Google Chrome a iné menšie prehliadače :) Aj keď celá QT časť bola vyhodená z projektu. Keď už hovoríme o WebKit. Gecko svojho času považoval za hlavného kandidáta na rolu HTML enginu aj Apple. Vzhľadom na prevahu technológie RPC - XPCOM v Gecku sa však zvolilo KHTML.

Aplikácie QT majú natívny vzhľad Aqua, ale sú trochu zastarané. Je to spôsobené tým, že QT používa Carbon na vykresľovanie widgetov a moderné rozhranie Mac OS X je napísaný väčšinou v Cocoa. Trolltech sa však neustále snaží zlepšovať vzhľad verzia pre mac a najnovšie verzie QT má teraz možnosť vytvárať natívne ponuky lišty nástrojov Mac OS X, ako aj doplnkové funkcie o interakcii s Dockom. QT má tiež podporu pre Growl.

Prečo QT? Ak potrebujete napísať malú aplikáciu s používateľským rozhraním a nepoznáte Objective C, potom je QT vašou voľbou, pretože učenie Carbon nemá ani veľký význam, ani žiadne viditeľné vyhliadky. Ak máte aplikáciu v C++ a potrebujete ju preniesť do Mac OS X, potom je čas zvoliť QT, pretože C++ má určité obmedzenia, keď je spárovaný s Objective C kódom. hlavne, aktualizovaná verzia QT, ktorý využíva Cocoa na vykresľovanie widgetov, je už za rohom, prvé snapshoty sú už dostupné.

Od slov k činom

Najprv si musíme stiahnuť GPL verziu QT, dá sa to urobiť z webovej stránky Trolltech http://trolltech.com/developer/downloads/qt/mac

Potrebujeme zhromaždiť tieto zdrojové kódy as možnosťou vytvorenia univerzálneho binárneho súboru (dovoľte mi pripomenúť, že musíte mať nainštalovaný spoločnosťou Apple XCode). Rozbaľte QT do adresára, ktorý vám vyhovuje, spustite terminál a v adresári QT spustite nasledujúci riadok:

./configure -universal -sdk /Developer/SDKs/MacOSX10.4u.sdk -fast –static

Tento príkaz nakonfiguruje QT na statické vytváranie statických knižníc do Universal Binary. Keďže UB aplikácie vytvorené staticky zaberajú pomerne veľa miesta, odporúčam pred vytvorením premenovať priečinok s príkladmi:
mv -R príklady príklady_

Teraz poďme zostaviť knižnicu pomocou príkazu make. V závislosti od výkonu vášho procesora môže montáž trvať od 20 minút do niekoľkých hodín. Po dokončení zostavy spustite v termináli nasledujúce príkazy:
vykonať inštaláciu
PATH=$PATH:/usr/local/Trolltech/QT-4.4.1/
export PATH

Upozorňujeme, že cesta k nainštalovanému QT sa líši od verzie k verzii. Teraz je všetko pripravené na ďalší vývoj.

Dobrý deň, QT

Poďme si teda vytvoriť jednoduchú UB aplikáciu s jedným tlačidlom a textovým štítkom. Za týmto účelom si v našom domovskom adresári vytvoríme zložku HelloQT. Spustite QT Designer, vyzerá to asi takto:

Vytvorte dialógový formulár a umiestnite naň widgety QPushButton a QLabel. Dajte im názvy objektov helloBt a helloLbl. Zavolajte samotný formulár helloDlg a uložte výsledky našich manipulácií do adresára projektu s názvom HelloDlg. Konečný výsledok bude vyzerať takto:

Teraz musíme napísať kód programu. Vytvorte súbory HelloDlg.cpp, HelloDlg.h, main.cpp a HelloQT. pro (súbor projektu QT) v adresári projektu.

V HelloQT. pre napíšte tieto riadky:

ZDROJE += HelloDlg.cpp main.cpp
HLAVIČKY += AhojDlg.h
FORMULÁRE += AhojDlg.ui
CONFIG += x86 ppc

QT používa svoj vlastný generátor makefile, qmake. Direktívy a formát qmake je možné podrobnejšie preskúmať pomocou QT Asistant. dávaj pozor na posledný riadok, tu jasne uvádzate, že máte záujem o aplikáciu Universal Binary.

Trolltech sa snaží zlepšiť integráciu QT a najpopulárnejších integrovaných vývojových prostredí, ale veci nie sú také dobré, ako by sme chceli. Máte dve možnosti: môžete skompilovať aplikáciu priamo z príkazového riadku, alebo môžete vytvoriť projekt XCode a pokračovať v písaní projektu priamo z tohto IDE. Preferujem druhú možnosť, generovanie z času na čas nový súbor. Spustiť z terminálu nasledujúce riadky:

qmake -spec macx-xcode HelloQT.pro

Teraz zostáva jediné dôležitou súčasťou. Zmeňte obsah súboru main.cpp na nasledujúce riadky:
#include

#include "AhojDlg.h"

int main(int argc, char *argv)
{
QApplication appl(argc, argv);
HelloDlg mainDlg;
mainDlg.show();
return appl.exec();
}


súbor HelloDlg. h by mal vyzerať takto:
#ifndef _HELLODLG_H_
#define _HELLODLG_H_

#include

#include "ui_HelloDlg.h"

class HelloDlg: public QDialog, Ui::helloDlg
{
Q_OBJECT

verejné:
AhojDlg();
~AhojDlg();

súkromné ​​sloty:
void onHelloBtClicked(bool);
};

#koniec Ak


A nakoniec HelloDlg.cpp:
#include "AhojDlg.h"

HelloDlg::HelloDlg(): QDialog(NULL)
{
Ui::helloDlg::setupUi(this );

Connect(helloBt, SIGNAL(clicked(bool )), this , SLOT(onHelloBtClicked(bool )));
}

HelloDlg::~AhojDlg()
{

void HelloDlg::onHelloBtClicked(bool )
{
helloLbl->setText(QString::fromUtf8("Ahoj QT" ));
}


Zastavme sa na tomto mieste a urobme si teoretickú exkurziu, aby sme nováčikom v QT tieto riadky trochu vysvetlili. Na odozvu na udalosti, ako sú kliknutia na tlačidlá, QT používa svoju vlastnú paradigmu signálu/slotu. Keďže jazyk C++ nemá dostatok funkcií, Trolltech sa rozhodol použiť vlastný moc preprocesor, ktorý som už spomínal. Makro Q_OBJECT to naznačuje túto triedu obsahuje sloty a vyžaduje špeciálne spracovanie QT preprocesor (tento proces sa nazýva moc"ing), každá takáto trieda musí priamo alebo nepriamo dediť z triedy QObject. Direktíva private slots naznačuje, že tieto metódy triedy sú súkromné ​​sloty, t. j. takzvané obslužné programy udalostí. Treba pridať že k jednému signálu môžete pripojiť veľa slotov, rovnako ako ku každému slotu môžete pripojiť ľubovoľný počet signálov.

Trieda Ui::helloDlg, nachádzajúca sa v mennom priestore používateľského rozhrania, je trieda, ktorú vytvára špeciálny preprocesor z formulárového súboru HelloDlg.ui (tento proces sa nazýva ui"ing). Súbor používateľského rozhrania je súbor xml formáte, ktorý popisuje formulár pripravený v QT Designer a jeho prvky.

To je všetko, poďme skompilovať aplikáciu. Buď z XCode stlačením cmd + B, alebo z terminálu príkazom:


Výsledky môžete vidieť na snímkach obrazovky:

Ak vás táto téma zaujíma, pýtajte sa v komentároch :)

Programovanie s Qt

Časť 1. Úvod. Vývojárske nástroje a objektový model

Obsahová séria:

1. Úvod

Existujú verzie Qt pre unixové verzie operačné systémy s X Window System (napríklad X.Org, Mac OS X a Windows OS). Qt Software tiež portuje svoj produkt mobilné platformy: Embedded Linux (EN), S60 (EN) a Windows CE. Qt poskytuje skvelé príležitosti pre multiplatformový vývoj väčšiny rôzne programy, nie nevyhnutne s grafickým rozhraním. Najmä je založený na populárne médium Pracovná plocha KDE (EN).

Sada nástrojov je rozdelená na modulov, z ktorých každý sa nachádza v samostatnej knižnici. Základné triedy sú v QtCore, komponenty GUI sú v QtGui, sieťové triedy sú v QtNetwork atď. Takto je možné kompilovať programy aj pre platformy, kde nie je X11 alebo iný kompatibilný grafický subsystém.

2. Inštalácia Qt

Budeme musieť nainštalovať vývojové prostredie Qt. softvér distribuované za podmienok bezplatnej licencie GPL 3.0 alebo LGPL 2.1. Môžete ho získať na adrese http://www.qtsoftware.com/downloads (EN).

2.1. Základné knižnice a nástroje

V úložiskách populárne distribúcie GNU/Linux už má hotové balíčky s vývojovým prostredím Qt (napríklad v Debiane, Fedore, Gentoo, Mandriva, Ubuntu). Používateľ však môže zostaviť a nainštalovať sadu nástrojov zo zdrojového kódu.

Pre systémy používajúce X11 si musíte stiahnuť súbor qt-x11-opensource-src-4.x.y.tar.gz, kde 4.x.y je najnovšia dostupná stabilná verzia. Nainštalujeme verziu 4.5.0.

V adresári so súborom qt-x11-opensource-src-4.5.0.tar.gz spustite nasledujúce príkazy:

tar xvfz qt-x11-opensource-src-4.5.0.tar.gz cd qt-x11-opensource-src-4.5.0

Pred vytvorením Qt spustite konfiguračný skript. Úplná sada jeho možností sa zobrazí pomocou príkazu ./configure -help , ale zvyčajne je možné použiť štandardné nastavenia.

Parameter -prefix určuje inštalačný adresár (predvolený je /usr/local/Trolltech/Qt-4.5.0). Existujú aj kľúče na inštaláciu rôznych komponentov (spustiteľné súbory, knižnice, dokumentácia atď.) do rôznych adresárov.

Pri spustení skript vyžaduje, aby používateľ súhlasil s podmienkami licencie GPL / LGPL. Po vykonaní

./configure

zostavenie a inštaláciu môžete spustiť pomocou príkazov:

vytvoriť a vykonať inštaláciu

Uvedomte si, že kompilácia trvá dlho a inštalácia Qt môže vyžadovať oprávnenia root (súbory sa zapisujú do /usr/local/).

Ak budete neskôr potrebovať prekonfigurovať a prebudovať Qt v rovnakom adresári, odstráňte všetky stopy predchádzajúcej konfigurácie pomocou make confclean pred opätovným spustením ./configure.

Spôsob spustiteľné súbory Je potrebné pridať Qt premenná prostredia PATH. V shelloch bash, ksh, zsh a sh to možno urobiť pridaním nasledujúcich riadkov do súboru ~/.profile:

PATH=/usr/local/Trolltech/Qt-4.5.0/bin:$PATH CESTA exportu

V csh a tcsh musíte do ~/.login pridať nasledujúci riadok:

setenv PATH /usr/local/Trolltech/Qt-4.5.0/bin:$PATH

Ak používate iný shell, pozrite si príslušné časti dokumentácie.

Okrem toho musíte do premennej LD_LIBRARY_PATH pridať riadok /usr/local/Trolltech/Qt-4.5.0/lib, ak kompilátor nepodporuje RPATH. Používame GNU/Linux a GCC (EN), takže tento krok vynechávame.

Potom použite pomôcku qtdemo na spustenie ukážkových aplikácií na testovanie funkčnosti nainštalovaných nástrojov.

2.2. SDK

Nedávno sa objavilo multiplatformové vývojové prostredie Qt Creator. Úplnú súpravu SDK vrátane IDE (okrem knižníc a základných vývojárskych nástrojov) možno nájsť na webovej stránke Qt Software. Stiahnite si binárny súbor qt-sdk-linux-x86-opensource-xxx.bin a spustite sprievodcu inštaláciou:

chmod +x ./qt-sdk-linux-x86-opensource-2009.01.bin ./qt-sdk-linux-x86-opensource-2009.01.bin

Ak sa nechystáte nainštalovať SDK do svojho domovského adresára, spustite inštalačný program s právami superužívateľa.


3. Vývojárske nástroje

Qt obsahuje vývojárske nástroje s grafickým alebo konzolovým rozhraním. Medzi nimi:

  • asistent je grafický nástroj na prezeranie hypertextovej dokumentácie pre nástroje a knižnice Qt.
  • designer je grafický nástroj na vytváranie a zostavovanie používateľských rozhraní založených na komponentoch Qt.
  • qmake je multiplatformový generátor Makefile.
  • moc je kompilátor metaobjektov (obslužný program rozšírenia Qt pre C++).
  • uic je kompilátor používateľských rozhraní zo súborov .ui vytvorených v Qt Designer.
  • rcc – kompilátor zdrojov zo súborov .qrc.
  • qtconfig – grafický inštalátor vlastné nastavenia pre aplikácie Qt.
  • qtdemo – spúšťa príklady a demo programy.
  • qt3to4 je nástroj na migráciu projektov z Qt 3 na Qt 4.
  • lingvist je nástroj na lokalizáciu aplikácií.
  • pixeltool – lupa obrazovky.


3.1. qmake

Nástroj qmake sa používa na automatické generovanie súborov Makefiles na rôznych platformách.

Vo všeobecnosti je qmake orientovaný na Qt. Ak máte záujem o multiplatformové zostavovacie systémy pre širšie účely, môžete sa obrátiť na CMake, ktorý tiež podporuje Qt.

Začiatočníci by sa mali držať qmake.

Kompletnú dokumentáciu pre tento nástroj nájdete v Qt Assistant. Qt sa dodáva aj s manuálovými stránkami vrátane qmake(1) (na príkazovom riadku zadajte man qmake). Tu poskytneme základné pokyny, ktoré vám pomôžu vytvoriť kód článku, ako aj vaše vlastné jednoduché projekty.

Ako príklad si vytvoríme adresár myproject a pridáme tam súbory hello.h, hello.cpp a main.cpp. V hello.h popisujeme prototyp funkcie hello():

Výpis 1.1. Vyhlásenia funkcií programu „Ahoj, svet!“
// ahoj.h void ahoj();

Implementácia hello() bude umiestnená v hello.cpp:

Výpis 1.2. Implementácia funkcií programu „Ahoj, svet!“
// ahoj.cpp #include #include "hello.h" void hello() ( qDebug()<< "Hello, World!"; }

Tu sa qDebug() používa na výstup informácií o ladení. Dá sa odstrániť deklarovaním symbolu QT_NO_DEBUG_OUTPUT počas kompilácie. Existuje aj funkcia qWarning(), ktorá vydáva varovania, a qFatal(), ktorá ukončí aplikáciu po vytlačení kritickej chybovej správy v STDERR (qCritical() robí to isté, ale bez ukončenia).

V hlavičkovom súbore obsahuje deklarácie, ktoré pridávajú pohodlnejšiu syntax operátora pre qDebug(), qWarning() a qCritical()<< . При этом между аргументами (как в случае qDebug() << a << b << c;) автоматически расставляются пробелы, поддерживается вывод многих типов C++ и Qt, а в конце автоматически добавляется перевод строки.

Hlavný kód aplikácie (tu sa riadime konvenciou vkladania main() do súboru main.cpp):

Výpis 1.3. Hlavná () funkcia programu „Ahoj, svet!“
// main.cpp #include "hello.h" int main() ( hello(); return 0; )

Ak chcete vytvoriť súbor projektu, spustite

Potom by sa mal objaviť súbor myproject.pro s približne nasledujúcim obsahom:

################################### # Automaticky generované qmake ########## ############################ TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input HEADERS += hello.h ZDROJE += hello.cpp main.cpp

Operátor = sa používa na priraďovanie hodnôt premenným, += pridáva do premennej novú možnosť, -= odstraňuje zadanú možnosť.

TEMPLATE = app znamená, že vytvárame aplikáciu; pre knižnicu použite TEMPLATE = lib .

TARGET – názov cieľového súboru (ak chcete získať spustiteľný súbor foobar, zadajte TARGET = foobar).

DEPENDPATH – adresáre na vyhľadávanie pri riešení závislostí.

INCLUDEPATH – adresáre s hlavičkovými súbormi.

Po spustení

vytvorí sa bežný Makefile založený na myproject.pro v GNU/Linux:

####### Kompilovať hello.o: hello.cpp hello.h $(CXX) -c $(CXXFLAGS) $ (INCPATH) -o hello.o hello.cpp main.o: main.cpp hello.h $(CXX) -c $(CXXFLAGS) $ (INCPATH) -o main.o main.cpp ####### Inštalovať inštaláciu: FORCE odinštalovať: FORCE FORCE:

Možnosti qmake ovplyvňujú obsah súboru Makefile. Napríklad qmake -Wall pridá -Wall k príznakom kompilátora – vypíše všetky varovania.

Pomocou príkazu make získame spustiteľný súbor myproject, ktorý na obrazovke zobrazí reťazec „Hello, World!“.

Táto schéma sa môže zdať príliš komplikovaná, ale v skutočných projektoch väčšinu práce na zostavovaní vykonáva qmake (napríklad spúšťa kompilátor metaobjektov).

3.2. Qt Creator

Vyššie popísané nástroje sú dostatočné na vývoj aplikácií. Môžete použiť svoj obľúbený textový editor, ako je GNU Emacs alebo Vim. Tradičné IDE ako KDevelop tiež pracujú s Qt.

Nedávno však spoločnosť Qt Software vydala svoj multiplatformový IDE Qt Creator. Má zabudované všetky vývojárske nástroje, editor so zvýrazňovaním a dokončovaním kódu, debugger (grafické rozhranie pre gdb) a podporu pre Perforce, SVN a Git.

Pri práci v Qt Creator sa používa niekoľko režimov, ktoré zodpovedajú kartám na paneli vľavo. Na rýchle prepínanie medzi režimami môžete použiť kombinácie kláves Ctrl+1, Ctrl+2 atď. Hlavne režim úprav zodpovedá Ctrl+2.


Na navigáciu v editore použite kombináciu kláves Ctrl+K. Po kliknutí naň musíte zadať jednu z predpôn:

Tabuľka 1. Predpony pre navigáciu v Qt Creator

Za predponou stlačte medzerník a zadajte príslušné informácie. Napríklad, ak chcete prejsť na riadok 93 aktuálneho súboru, musíte zadať „l 93“ (to isté sa dá urobiť pomocou Ctrl+L), prejsť na dokumentáciu k téme qobject_cast – „? qobject_cast“ atď.

V spodnej časti okna sa zobrazí pole s automatickým dokončením.

Obrázok 5. Navigačné pole v Qt Creator

Tabuľka 2. Klávesové skratky pre Qt Creator

Ctrl+[Prejdite na začiatok bloku
Ctrl+]Prejdite na koniec bloku
Ctrl+UVyberte blok
Ctrl+Shift+UZrušte výber bloku
Ctrl+IZarovnať blok
Ctrl+< Zbaliť blok
Ctrl+>Rozbaliť blok
Ctrl+/Komentujte blok
Ctrl+Shift+Posunúť riadok vyššie
Ctrl+Shift+↓Posuňte riadok nadol
shift+DelSDelete line

Vstavaný editor implementuje „inteligentné“ pridávanie kódu, ktoré sa volá kombináciou kláves Ctrl+<Пробел>. Základňa symbolov je zostavená na základe súborov hlavičiek projektu z INCLUDEPATH.

V IDE je samostatná sekcia na čítanie dokumentácie. pomocný režim. Ak chcete získať kontextovú pomoc pre triedu alebo metódu, jednoducho presuňte textový kurzor na názov a stlačte F1. Užitočná je aj klávesa F2, ktorá sa presúva na definíciu v hlavičkových súboroch.

Ak chcete prepnúť z režimu pomocníka alebo ladenia do režimu základných úprav, stlačte kláves Esc. V režime úprav Esc presunie zameranie z ďalších okien (ako je výstup kompilácie alebo kontextová pomoc) do editora. Ak znova stlačíte Esc, ďalšie okná sa zatvoria.

Podobne ako qmake, aj Qt Creator používa súbory .pro, takže staré ručne vytvorené projekty možno ľahko importovať do IDE. K dispozícii je aj sprievodca, pomocou ktorého môžete vytvoriť šablónu pre nový projekt.

Qt Creator je momentálne v aktívnom vývoji, ale ak chcete klasické Qt IDE, ktoré funguje na rôznych platformách, toto je najlepšia možnosť.

4. Qt štýl

V Qt sa používa CamelCasing: Názvy tried vyzerajú ako MyClassName a názvy metód vyzerajú ako myMethodName.

Navyše všetky názvy tried Qt začínajú Q, napríklad QObject, QList alebo QFont.

Väčšina tried má zodpovedajúce hlavičkové súbory s rovnakým názvom (bez prípony .h), t.j. treba použiť:

#include #include #include

Preto v budúcnosti nebudeme samostatne určovať, kde je tá alebo oná trieda deklarovaná.

Spôsoby získania a nastavenia vlastnosti (getter A stavač) sú pomenované nasledovne: Vlastnosť fooBar možno získať pomocou metódy fooBar() a nastaviť pomocou setFooBar() .

T fooBar() const; void setFooBar(T val);

Pri vývoji vlastných aplikácií v Qt by ste sa mali držať tohto štýlu.

5. Objektový model

Na efektívnu prácu s triedami za behu používa Qt špeciálny objektový model, ktorý rozširuje model C++. Pridávajú sa najmä tieto funkcie:

  • stromové hierarchie objektov;
  • analóg dynamic_cast pre knižnicu, ktorá nepoužíva RTTI;
  • interakcia predmetov prostredníctvom signály A sloty;
  • vlastnosti predmetov.

Mnoho objektov je definovaných hodnotou niekoľkých vlastností, vnútorných stavov a spojení s inými objektmi. Sú to jednotlivé entity a prevádzka doslovného kopírovania, ako aj zdieľanie dát v pamäti pre nich nedáva zmysel. V Qt tieto objekty zdedia vlastnosti QObject.

V prípadoch, keď by sa s objektom malo zaobchádzať nie ako s entitou, ale ako s hodnotou (napríklad pri uložení do kontajnera), sa používajú ukazovatele. Niekedy sa ukazovateľ na objekt, ktorý zdedí z QObject, nazýva jednoducho objekt.

Sada nástrojov je navrhnutá tak, že pre QObject a všetkých jeho potomkov nie sú k dispozícii konštruktor kopírovania a operátor priradenia - sú deklarované v súkromnej sekcii prostredníctvom makra Q_DISABLE_COPY():

class FooBar: public QObject ( private: Q_DISABLE_COPY(FooBar) );

Buďte opatrní a nepoužívajte štruktúru

Foo bar = Foo(baz);

Ostatné objekty (ako sú kontajnery a reťazce) sú úplne definované údajmi, ktoré reprezentujú, takže ich zodpovedajúce triedy majú operátor priradenia a konštruktor kopírovania. Okrem toho objekty reprezentujúce rovnaké dáta ich môžu v pamäti oddeliť transparentne pre programátora.


5.1. Metaobjektový systém

Niektoré rozšírenia sú implementované pomocou štandardných metód C++, ale Qt používa aj zložitejšie syntaktické rozšírenia, takže využíva automatické generovanie kódu.

Na tento účel C++ implementuje mechanizmus šablón, ktorý však neposkytuje všetky potrebné schopnosti Qt, je slabo kompatibilný s dynamickým objektovým modelom a nie je plne podporovaný všetkými verziami kompilátorov.

V ťažkých situáciách používa Qt svoje kompilátor meta objektov moc , ktorý konvertuje kód s rozšíreniami na štandardný kód C++. Na označenie, že trieda používa schopnosti metaobjektov (a preto by ju mal spracovať moc), musí byť makro Q_OBJECT špecifikované v súkromnej sekcii.

Ak narazíte na podivné chyby pri kompilácii, ktoré hovoria, že trieda nemá definovaný konštruktor alebo nemá tabuľku virtuálnych funkcií (vtbl), s najväčšou pravdepodobnosťou ste zabudli kód vygenerovaný moc. Zvyčajne sa to stane, ak nie je zadané makro Q_OBJECT.

Aby ste sa vyhli chybám, je lepšie použiť Q_OBJECT vo všetkých triedach, ktoré dedia z QObject (nepriamo alebo priamo).

Použitie dynamického prístupu je spojené s určitými stratami výkonu v porovnaní so statickým, ale tieto režijné náklady je možné zanedbať, ak sa zohľadnia získané výhody.

Metaobjektový kód okrem iného pridáva metódu

virtual const QMetaObject* QObject::metaObject() const;

ktorý vracia ukazovateľ na meta objekt objektu.

Signály, sloty a vlastnosti sú založené na systéme meta-objektov.

Pri dedení z QObject si uvedomte obmedzenia uložené moc:

  1. Pri viacnásobnom dedení musí byť potomok QObject prvou a jedinou prvou zdedenou triedou: class MyClass: public QObject, public Foo, public Bar ( // ... );
  2. Virtuálne dedičstvo nie je podporované s QObject.

5.2. qobject_cast

Na dynamické pretypovanie QObject použite funkciu

T qobject_cast(QObject *object);

Funguje ako štandardná operácia dynamic_cast v C++, ale nevyžaduje podporu RTTI.

Majme triedu MyClass1, ktorá dedí z QObject a MyClass2, dedí z MyClass1:

#include trieda MyClass1: public QObject ( Q_OBJECT public: MyClass1(); // ... ); trieda MojaTrieda2: verejná MojaTrieda1 ( Q_OBJECT public: MojaTrieda2(); // ... );

Dynamické odlievanie je znázornené nasledujúcim kódom:

QObject *a = new MyClass2; MyClass1 *b = qobject_cast (a); MyClass2 *c = qobject_cast (b);

Tieto operácie budú fungovať správne za behu.

Rovnako ako pri dynamic_cast , výsledok pretypovania možno skontrolovať:

if (b = qobject_cast (a)) ( // ... )

Systém metaobjektov vám tiež umožňuje skontrolovať, či a zdedí triedu MyClass1:

if (a->inherits("MyClass1")) ( b = statické_cast (a); //...)

Uprednostňuje sa však predchádzajúca možnosť s qobject_cast.

5.3. Objektové stromy

Objekty tried, ktoré dedia z QObject, môžu byť organizované v stromovej štruktúre. Keď je objekt vymazaný, Qt ho vymaže detské predmety, ktoré následne vymažú svoje podriadené objekty atď. Inými slovami, odstránením objektu sa vymaže celý podstrom, ktorého je koreňom.

Majme triedy ClassA a ClassB:

Výpis 2.1. Deklarácia MyClass pre program demonštrujúci, ako sa objekty vytvárajú a vymazávajú
// myclass.h #include class MyClass: public QObject ( public: MyClass (id znaku, QObject *parent = 0); ~MyClass(); private: char id_; );
Výpis 2.2. Definovanie metód MyClass pre program, ktorý demonštruje, ako sa objekty vytvárajú a vymazávajú
// myclass.cpp #include #include #include "myclass.h" MojaTrieda::MojaTrieda (id znaku, QObject *rodič) : QObject(parent), id_(id) ( qDebug()<< "+" >> id_; ) MyClass::~MyClass() ( qDebug()<< "-" >> id_; )

Tu je rodičovský objekt nastavený v konštruktore QObject:

QObject::QObject(QObject *rodič = 0);

Dá sa nastaviť neskôr pomocou metódy setParent() a získať pomocou parent() :

void QObject::setParent(QObject *parent);
QObject* QObject::parent() const;

Ak vytvoríte jeden z každého z objektov A a B v zásobníku, potom sa vytvorí najskôr A, potom B. V súlade so štandardom C++ sa vymazanie uskutoční v opačnom poradí - najprv B, potom A:

Výpis 2.3. Vytváranie inštancií MyClass v zásobníku
// main.cpp #include "myclass.h" int main() ( MojaTrieda a ("A"); MojaTrieda b ("B"); return 0; )

Ak vytvoríte B na hromade a priradíte ju ako dieťa A, potom B sa automaticky odstráni spolu s A:

Výpis 2.4. Vytvorenie inštancie A triedy MyClass v zásobníku a inštancie B v halde ako potomka triedy A
// main.cpp #include "myclass.h" int main() ( MojaTrieda a ("A"); MojaTrieda *b = new MojaTrieda ("B", &a); return 0; )

Podobne pre zložitejšie stromy:

Obrázok 8. Príklad viacúrovňového stromu objektov
Výpis 2.5. Viacúrovňový strom objektov zakorenených v zásobníku
// main.cpp #include "myclass.h" int main() ( MojaTrieda a ("A"); MojaTrieda *b = nová MojaTrieda ("B", &a); MojaTrieda *c = nová MojaTrieda ("C", &a); MojaTrieda *d = nová MojaTrieda("D", c);

Po vymazaní A sa vymaže celý strom.

Programátor teda musí vytvárať objekty na halde a nastavovať príslušné hierarchie a Qt sa stará o správu pamäte.

Ak sa v zásobníku vytvorí objekt a jeho potomkovia, toto poradie odstraňovania môže spôsobiť chyby.

int main() ( MojaTrieda b ("B"); MojaTrieda a ("A"); b.setParent(&a); // ... return 0; )

Tu, keď opustíte rozsah, objekt A bude vymazaný ako prvý, pretože bol naposledy vytvorený. V tomto prípade Qt vymaže aj svoj podriadený objekt B. Potom sa však urobí pokus o vymazanie B, čo bude mať za následok chybu.

V opačnom prípade nebude problém, pretože pri volaní deštruktora QObject sa objekt sám odstráni zo zoznamu podriadených objektov nadradeného objektu:

int main() ( MojaTrieda a ("A"); MojaTrieda b ("B", &a); // ... návrat 0; )

Vo všeobecnosti by mali byť podradené objekty alokované na halde.

Každý QObject má vlastnosť objectName, ku ktorej sa pristupuje pomocou metód

QString objectName() const; void setObjectName(const QString& meno);

V predvolenom nastavení je objectName prázdny reťazec. Prostredníctvom tejto vlastnosti možno objektom v strome priradiť názvy pre následné vyhľadávanie.

const QList &children() const;

– vráti zoznam podriadených objektov.

T findChild(const QString& meno = QString()) const;

– vráti podradený objekt s názvom názov, ktorý možno pretypovať na typ T alebo 0, ak sa takýto objekt nenájde. Žiadny argument názov vráti všetky podradené objekty. Vyhľadávanie sa vykonáva rekurzívne.

QList QObject::findChildren(const QString& meno = QString()) const;

– vráti všetky podradené objekty s názvom názov, ktorý je možné pretypovať na typ T, alebo prázdny zoznam, ak sa žiadne takéto objekty nenájdu. Žiadny argument názov vráti všetky podradené objekty. Vyhľadávanie sa vykonáva rekurzívne.

QList QObject::findChildren (const QRegExp& regExp) const;

– podobné, ale s vyhľadávaním regulárnych výrazov regExp.

void dumpObjectTree();

– zobrazuje ladiace informácie o strome objektov s daným koreňom.

5.4. Signály a sloty

Pri vytváraní grafických používateľských rozhraní sa interakcia s objektom často uskutočňuje prostredníctvom spätných volaní, t.j. odovzdanie kódu pre následné vykonanie (vo forme ukazovateľov funkcií, funktorov atď.). Tiež populárny koncept diania A spracovateľov, v ktorom handler funguje ako zachytávač udalostí pre konkrétny objekt.

Qt predstavuje koncept signálov a slotov.

Signál odoslaná pri zavolaní zodpovedajúcej metódy. Programátor potrebuje iba špecifikovať prototyp metódy v sekcii signálov.

Slot je metóda vykonaná pri prijatí signálu. Sloty môžu byť deklarované ako verejné sloty, chránené sloty alebo súkromné ​​sloty. V tomto prípade úroveň ochrany ovplyvňuje iba schopnosť volať sloty ako bežné metódy, ale nie schopnosť pripojiť signály k slotom.

Model signálu a slotu sa líši od modelu udalosti a obsluhy v tom, že slot sa môže pripojiť k akémukoľvek počtu signálov a signál sa môže pripojiť k akémukoľvek počtu slotov. Pri odoslaní signálu budú volané všetky sloty, ktoré sú k nemu pripojené (poradie volaní nie je definované).

5.4.1. Oznamovanie signálov a slotov, odosielanie signálov

Ako typický príklad slotu zvážte spôsob získania vlastnosti ( getter). Spôsob nastavenia vlastnosti ( stavač) v tomto prípade bude signál zodpovedať.

Zoznam 3.1. Trieda MyClass so slotom void setValue(int x) a signálom void valueChanged(int x)
// myclass.h #include class MyClass: public QObject ( Q_OBJECT public: MyClass(int x, QObject *parent = 0); int value() const; verejné priestory: void setValue (int x); signály: void valueChanged (int x); private: int x_ ;

Všimnite si makro Q_OBJECT, ktoré signalizuje Qt, že sa používa systém metaobjektov.

Zoznam 3.2. Implementácia metód triedy MyClass so signálom void setValue(int x) a void valueChanged(int x)
// myclass.cpp #include #include "myclass.h" MojaTrieda::MojaTrieda (int x, QObject *parent) : QObject(parent) ( setValue (x); ) int MyClass::value() const ( return x_; ) void MojaTrieda::setValue ( int x) ( if (x_ == x) return; x_ = x; emit valueChanged (x); )

Kľúčové slovo emit je zodpovedné za odoslanie signálu.

Pre signál je špecifikovaný iba prototyp a signál nemôže vrátiť hodnotu (t. j. je špecifikované void). Za implementáciu je zodpovedný kompilátor meta-objektov, ktorý tiež konvertuje rozšírenú syntax s kľúčovými slovami signály, sloty, emit do štandardného kódu C++.

V skutočnosti môžu byť kľúčové slová nahradené makrami Q_SIGNALS, Q_SLOTS a Q_EMIT. Je to užitočné, ak používate knižnice tretích strán, ktoré už používajú slová signály, sloty alebo emitovať.

Spracovanie kľúčových slov je vypnuté príznakom no_keywords. V súbore projektu qmake (.pro) pridajte

CONFIG += no_keywords

Môžete sa pozrieť na výstup kompilátora metaobjektov v súbore moc_slots.cpp, ktorý je vygenerovaný zo slots.ha skompilovaný spolu so zvyškom súborov .cpp.

5.4.2. Pripojenie signálu k slotu

Zoznam 3.3. Pripojenie signálu void MyClass::valueChanged (int x) do slotu void MyClass::setValue (int x)
// main.cpp #include #include #include "myclass.h" int main() ( MojaTrieda a(1); MojaTrieda b(2); QObject::connect (&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); a.setValue(3);<< "a:" << a.value(); // 3 qDebug() << "b:" << b.value(); // 3 return 0; }

Tu je pomocou QObject::connect signál objektu a pripojený k slotu objektu b (prechádzajú sa ukazovatele na QObject). Makrá SIGNAL a SLOT tvoria reťazcové podpisy pre metódy. Ich argumenty musia obsahovať prototypy bez uvedenia názvov premenných, t.j. SIGNAL(valueChanged(int x)) nie je platná možnosť.

Podpisy sa používajú na porovnávanie typov: podpis signálu sa musí zhodovať s podpisom slotu. V tomto prípade môže byť podpis slotu kratší, ak sa ignorujú ďalšie argumenty.

Ďalšia možnosť volania QObject::connect:

b.connect(&a, SIGNAL(valueChanged(int)), SLOT(setValue(int)));

Takže tu, volanie MyClass::setValue na a spustí MyClass::setValue na b .

Venujte pozornosť riadku if (x_ == x) return; . Je potrebné vyhnúť sa problémom s cyklickými spojeniami. Fungovať bude napríklad nasledujúci kód:

Výpis 3.4. Cyklické spájanie signálov void MyClass::valueChanged (int x) so slotmi void MyClass::setValue (int x)
// main.cpp #include #include #include "slots.h" int main() ( MojaTrieda a(0); MojaTrieda b(1); MojaTrieda c(2); QObject::connect (&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue (int))); QObject::connect (&b, SIGNAL(hodnotaZmenená(int)), &c, SLOT(nastav.hodnota(int))); (setValue(int)));<< "a:" << a.value(); // 3 qDebug() << "b:" << b.value(); // 3 qDebug() << "c:" << c.value(); // 3 return 0; }

QObject::connect vráti hodnotu true, ak je pripojenie úspešné, a hodnotu false v opačnom prípade – napríklad, keď sa signál alebo slot nenájde alebo ich podpisy sú nekompatibilné.

Ak pridáte rovnaké pripojenia pomocou QObject::connect, slot sa zavolá niekoľkokrát.

5.4.3. Vypnúť

Na odpojenie signálu zo slotu použite QObject::disconnect:

QObject::disconnect (&a, SIGNAL(hodnotaChanged(int)), &b, SLOT(setValue(int)));

Ak je vypnutie úspešné, vráti sa true.

Ak namiesto signálu (SIGNAL(...)) zadáte 0, potom tento prijímač signálu (b) a slot sú odpojené od akéhokoľvek signálu:

QObject::disconnect (&a, 0, &b, SLOT(setValue(int)));

Ak zadáte 0 namiesto prijímača signálu (b) a slotu (SLOT(...)), potom bude všetko pripojené k tomuto signálu vypnuté:

QObject::disconnect (&a, SIGNAL(valueChanged(int)), 0, 0);

Ak zadáte 0 namiesto slotu (SLOT(...)), všetko pripojené k tomuto prijímaču signálu (b) bude vypnuté:

QObject::disconnect (&a, SIGNAL(valueChanged(int)), &b, 0);

Získame nasledujúce možnosti volania QObject::disconnect:

// Odpojí všetko od signálov odosielaných objektom a: QObject::disconnect (&a, 0, 0, 0); // To isté, ale vo forme metódy: a.disconnect(); // Odpoj všetko od signálu SIGNAL(...) odosielaného objektom a: QObject::disconnect (&a, SIGNAL(...), 0, 0); // To isté, ale vo forme metódy: a.disconnect (SIGNAL(...)); // Odpojte tento prijímač b: QObject::disconnect (&a, 0, &b, 0); // To isté, ale vo forme metódy a: a.disconnect (&b);

Keď vymažete jeden z objektov pripojenia, Qt automaticky vymaže samotné pripojenie.

5.4.4. Obmedzenia

Kompilátor metaobjektov má množstvo obmedzení, ktoré platia aj pre prácu so signálmi a slotmi.

  1. moc nespracúva šablóny ani makrá, takže šablóny tried nemôžu definovať signály a sloty a makrá sa nedajú použiť pri deklarovaní signálov a slotov (vrátane pri špecifikovaní parametrov).

    Makrá nemožno použiť v žiadnych oblastiach kódu, ktoré musí spracovať moc . Konkrétne cez ne nemôžete zadať základnú triedu.

    Je však možné použiť niektoré funkcie preprocesora. K dispozícii sú jednoduché podmienené konštrukcie (s direktívami #if, #ifdef, #ifndef, #else, #elif, #endif, ako aj definovaným špeciálnym operátorom). Na vytváranie deklarácií má moc možnosť príkazového riadka -D . Pomôcka qmake prejde na overenie všetkých deklarácií uvedených v parametri projektu DEFINES.

    Napríklad moc správne spracuje

    #if 0 // Ignorovaný blok #endif
    Blokovať #ifdef FOO // ... #endif

    bude tiež spracovaný iba vtedy, ak sa volá moc -DFOO, alebo ak je pred ním riadok #define FOO.

  2. Typy musia byť špecifikované celé, pretože QObject::connect() ich doslova porovnáva. Konkrétne, ak je enumerácia Bar definovaná v triede Foo, potom musí byť Foo::Bar špecifikovaný v argumentoch signálu:

    class Foo: public QObject ( Q_OBJECT enum Bar ( a, b, c ); signály: void somethingHappened (Foo::Bar x); );
  3. Ukazovatele funkcií nemožno použiť ako parametre signálu a slotu. Napríklad,

    int (*zábava)(int)

    nie je platný argument. Môžete použiť typedef:

    typedef int (*zábava)(int);

    Zvyčajne je lepšie použiť dedičnosť a virtuálne funkcie namiesto ukazovateľov.

  4. Vnorené triedy nemôžu obsahovať signály a sloty.
  5. Signály a sloty, ktoré vracajú referencie, sa považujú za neplatné.
  6. Sekcie signálov a slotov môžu deklarovať iba signály a sloty.

5.5. Vlastnosti

Trieda, ktorá zdedí QObject, môže obsahovať deklaráciu vlastnosti pomocou makra Q_PROPERTY():

Q_PROPERTY( zadajte názov

ČÍTAŤ getFunction

Požadované parametre makra:

  • typu– typ nehnuteľnosti;
  • názov– názov nehnuteľnosti;
  • getFunction– metóda const na čítanie hodnoty; návratový typ musí byť typ, typ* alebo typ&.

Voliteľné makro parametre:

  • setFunction– metóda na nastavenie hodnoty vlastnosti, musí vrátiť hodnotu void a prijať iba jeden argument typu typ, typ*, alebo typ&;
  • resetFunction– metóda na nastavenie predvolenej hodnoty vlastnosti, ktorá závisí od kontextu, nesmie mať žiadne argumenty a vrátiť hodnotu void ;

Metódy môžu byť virtuálne alebo zdedené zo základnej triedy. Pre viacnásobné dedičstvo musia patriť do prvej triedy v zozname.

Pre voliteľné atribúty DESIGNABLE, SCRIPTABLE, STORED, USER, sú povolené boolovské hodnoty:

  • DESIGNABLE – či sa má vlastnosť zobraziť v Qt Designer a podobných grafických programoch. Predvolená hodnota je true , ale môžete zadať aj boolovskú metódu.
  • SCRIPTABLE – či má byť vlastnosť viditeľná pre skriptovací nástroj. Predvolená hodnota je true , ale môžete zadať aj boolovskú metódu.
  • STORED – či sa má vlastnosť uložiť pri ukladaní stavu objektu, alebo či sa počíta cez iné vlastnosti. Predvolená hodnota je true .
  • POUŽÍVATEĽ – či je vlastnosť upraviteľná používateľom. Triedy zodpovedajúce ovládacím prvkom majú zvyčajne jednu takúto vlastnosť. Predvolená hodnota je false .

Napríklad QWidget okrem iného deklaruje nasledujúce vlastnosti:

Q_PROPERTY (Qveľkosť minimálna veľkosť READ minimálna veľkosť WRITE sadaMinimumSize) Q_PROPERTY(int minimálna šírka READ minimálna šírka WRITE sadaMinimumWidth STORED false DESIGNABLE false) Q_PROPERTY (int minimálna výška READ minimálnaVýška WRITE setMinimumHeight STORABLE false)

Vlastnosť minimumSize je typu QSize a možno ju získať pomocou QSize minimumSize() const a nastaviť pomocou void setMinimumSize (const QSize&). minimumWidth a minimumHeight sa vypočítavajú cez minimumSize, takže sú nastavené na STORED false.

Príklad vlastnosti s atribútom USER – text v QLineEdit:

Q_PROPERTY(QString text READ text WRITE setText USER true)

Na čítanie a zápis vlastností sa používajú nasledujúce metódy:

QVariant QObject::vlastnosť (const char * meno) const; bool QObject::setProperty (const char * meno, const QVariant& hodnota);

property() tiež vráti hodnotu vlastnosti nesprávna možnosť QVariant, ak takáto vlastnosť neexistuje.

setProperty() vráti hodnotu true, ak má objekt špecifikovanú vlastnosť s typom kompatibilným s odovzdanou hodnotou. V opačnom prípade sa vráti false.

Ak trieda nemá špecifikovanú vlastnosť, potom sa pridá dynamická vlastnosť objekt. Zoznam dynamických vlastností je možné získať pomocou

QList QObject::dynamicPropertyNames() const;

Pozrime sa na príklad použitia vlastností. Nechajte triedu MyClass mať text vlastnosti reťazca (typu QString):

Zoznam 4.1. Deklarácia triedy MyClass s vlastnosťou text
// myclass.h #include #include class MyClass: public QObject ( Q_OBJECT Q_PROPERTY(QString text PREČÍTAJTE text WRITE setText) public: MyClass(QString text, QObject *parent = 0); QString text() const; void setText(const QString& text); private: QString text_; ) ;
Zoznam 4.2. Definovanie metód triedy MyClass s vlastnosťou text
// myclass.cpp #include #include #include "myclass.h" MojaTrieda::MojaTrieda(QString text, QObject *nadradený) : QObject(rodič) ( setText(text); ) QString MojaTrieda::text() const ( return text_; ) void MojaTrieda::setText( const QString& text) ( text_ = text; )

Práca s nehnuteľnosťou:

Výpis 4.3. Práca s vlastnosťou text objektu MyClass
// main.cpp #include #include #include #include #include #include #include "myclass.h" int main() ( MyClass str("foo"); qDebug()<< "text:" << str.text(); // Через метод: str.setText("bar"); qDebug() << "text:" << str.text(); // Через setProperty() / property(): str.setProperty("text", QVariant("baz")); QVariant prop = str.property("text"); qDebug() << "text:" << prop.toString(); // Добавление динамического свойства: str.setProperty("foo", QVariant("bob")); str.setProperty("bar", QVariant("slack")); QListd_props = str.dynamicPropertyNames(); QListIterator iter(d_props); // (Na kontajnery a iterátory sa pozrieme oddelene) while (iter.hasNext()) ( const char* d_prop_name = iter.next().data(); QVariant d_prop = str.property(d_prop_name); qDebug()<< "" << d_prop_name << ":" << d_prop.toString(); } return 0; }

Program by mal zobraziť nasledovné:

text: "foo" text: "bar" text: "baz" foo: "bob" bar: "slack"

Samozrejme, je bezpečnejšie a rýchlejšie volať metódy špecifickej triedy na čítanie a zápis vlastností. property() a setProperty() sú potrebné, keď o triede nie je známe nič okrem mien a typov vlastností.

Ak nepoznáte ani zoznam vlastností a metód pre triedu, môžete použiť metaobjekt.

5.6. Práca s MetaObjects

Metóda vráti meta objekt

QObject::metaObject()

Dá sa použiť na dynamické získavanie informácií o triede, ako napríklad v Java Reflecion API.

5.6.1. základné informácie

Vráti sa názov triedy

const char * QMetaObject::className() const;

Ukazovateľ na metaobjekt základnej triedy –

const QMetaObject* superClass() const;

5.6.2. Metódy

Iba tieto metódy a konštruktory sú dostupné prostredníctvom systému metaobjektov, ak je pred ich deklaráciami zadané makro Q_INVOKABLE:

class MyClass: public QObject ( Q_OBJECT public: Q_INVOKABLE MyClass(); // viditeľné pre systém metaobjektov Q_INVOKABLE void foo(); // viditeľné void foo(); // nie je viditeľné );

Na prístup k metódam (vrátane signálov a slotov) použite

int QMetaObject::methodCount() const; int QMetaObject::methodOffset() const; QMetaMethod QMetaObject::method (int index) const;

Metódy a vlastnosti tried sú indexované. K metóde sa pristupuje pomocou indexu cez QMetaObject::method() .

Celkový počet metód vrátane zdedených metód vráti QMetaObject::methodCount() . Zaujatosť metódy triedy vráti QMetaObject::methodOffset() , ukazuje, na akom indexe začínajú metódy tejto triedy. Posun sa zvyšuje s dedením a zobrazuje počet metód základnej triedy.

Príklad návodu na metódu:

const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->methodOffset(); i< m_obj->methodCount(); i++) ( qDebug()<< m_obj->metóda(i).podpis(); )

Ak by sme začali na indexe 0, získali by sme metódy zo všetkých základných tried vrátane QObject:

zničil(QObject*) deleted() deleteLater() _q_reregisterTimers(void*) ...

Metódy začínajúce na _q_ používa interne Qt a nie sú súčasťou API.

Konštruktéri sú špecifikovaní samostatne:

QMetaMethod QMetaObject::konštruktor (int index) const; int QMetaObject::constructorCount() const;

Napríklad dostaneme zoznam konštruktorov QObject:

Výpis 5. Odvodzovanie konštruktérov QObject cez systém metaobjektov
#include #include #include #include int main() ( QObject obj; const QMetaObject* m_obj = obj.metaObject(); for (int i = 0; i< m_obj->konstruktorPocet(); i++) ( qDebug()<< m_obj->konstruktor(i).podpis(); ) návrat 0; )

výsledok:

QObject(QObject*) QObject()

Index metódy, signálu, slotu alebo konštruktora možno získať ich podpisom:

int QMetaObject::indexOfConstructor (const char * konstruktor) const; int QMetaObject::indexOfMethod (metóda const char *) const; int QMetaObject::indexOfSignal (const char * signal) const; int QMetaObject::indexOfSlot (const char * slot) const;

Pre konštruktérov sa očakávajú metódy alebo signály normalizované podpisy. Môžu byť získané pomocou statickej metódy

static QByteArray QMetaObject::normalizedSignature(const char * metóda);

Napríklad,

QMetaObject::normalizedSignature("int * foo(const QString &, QObject *)")

vráti " int*foo(QString,QObject*)".

Funguje rovnakým spôsobom

statický QByteArray QMetaObject::normalizedType (const char * typ);

Ide o textové preliatie do kanonickej formy, ktoré sa používa najmä pri kontrole kompatibility signálu a slotu.

5.6.3. Vlastnosti

Rovnakým spôsobom môžete pracovať s vlastnosťami.

int QMetaObject::propertyCount() const; int QMetaObject::propertyOffset() const; QMetaProperty QMetaObject::vlastnost (int index) const;const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->propertyOffset(); i< m_obj->>pocet vlastnosti(); i++) ( qDebug()<< m_obj->property(i).name(); )

(Ak sa pozriete na všetky vlastnosti, vrátane zdedených, uvidíte aspoň objectName z QObject .)

Index vlastnosti možno získať podľa jej názvu:

int QMetaObject::indexOfProperty (const char * meno) const;

5.6.4. Prestupy

Enumerácie sú registrované v triede pomocou makra Q_ENUMS().

Zavolá sa enumerácia, ktorej hodnoty možno kombinovať pomocou bitového OR vlajka a musí byť zaregistrovaný pomocou Q_FLAGS() .

QMetaEnum QMetaObject: :enumerator (int index) const; int QMetaObject::enumeratorCount() const; int QMetaObject::enumeratorOffset() const;
Výpis 6.1. Trieda MyClass s vymenovaním typu a príznakom režimu
trieda MyClass ( Q_OBJECT Q_ENUMS(Type) Q_FLAGS(Mode) public: enum Type ( A, B, C ); enum Mode ( Read = 0x1, Write = 0x2, Execute = 0x4 ); // ... );

Vlajky sa používajú takto:

int režim = MyClass::Prečítať | MyClass::Write; // ... if (režim & MyClass::Write) // Je nastavený príznak zápisu? ( // ... )

Dynamická práca s enumeráciami:

Výpis 6.2. Výstup enumerácií a príznakov MyClass prostredníctvom systému metaobjektov
MyClsobj; const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->enumeratorOffset() ; i< m_obj->enumeratorCount(); i++) ( QMetaEnum me = m_obj->enumerator(i); if (me.isValid()) // Existuje názov ( if (me.isFlag()) // Príznak ( qDebug()<< "" << me.scope() << "::" << me.name(); } else { qDebug() << me.scope() << "::" << me.name(); } } }

výsledok:

MyClass::Typ MyClass::Mode

Index enumerácie možno získať podľa jeho názvu:

int QMetaObject::indexOfEnumerator (const char * meno) const;

5.6.5. CLASSINFO

Pomocou makra Q_CLASSINFO() môžete do metaobjektu pridať páry názov-hodnota. Napríklad,

Výpis 7.1. Trieda MyClass s CLASSINFO
trieda MojaTrieda ( Q_OBJECT Q_CLASSINFO("autor", "Bob Dobbs") Q_CLASSINFO("verzia", ​​"0,23") // ... );

Tieto páry sú zdedené a možno ich získať z metaobjektu pomocou rovnakej schémy:

QMetaClassInfo QMetaObject:: classInfo (int index) const; int QMetaObject::classInfoCount() const; int QMetaObject::classInfoOffset() const;

Pre príklad vyššie:

Výpis 7.2. Výstup CLASSINFO triedy MyClass
MyClsobj; const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->classInfoOffset(); i< m_obj->classInfoCount(); i++) ( QMetaClassInfo mci = m_obj->classInfo(i); qDebug()<< mci.name() << ":" << mci.value(); }

výsledok:

Index CLASSINFO je možné získať podľa jeho názvu:

int QMetaObject::indexOfClassInfo (const char * meno) const;

5.6.6. Volanie konštruktérov a metód

Argumenty sa prenášajú cez objekty QGenericArgument a QGenericReturnArgument. Vytvárajú ich makrá Q_ARG a Q_RETURN_ARG.

// const odkaz na odovzdanie hodnoty: Q_ARG (T, const T& hodnota) // odkaz na vrátenie hodnoty: Q_RETURN_ARG (T, T& hodnota)

Príklad použitia:

Q_ARG(QString; "foo") Q_ARG(int, 23) Q_RETURN_ARG(QReťazec, reťazec)

Na vytvorenie novej inštancie triedy použite metódu newInstance() metaobjektu, ktorej je možné odovzdať až 10 argumentov.

QObject* QMetaObject::newInstance (QGenericArgument hodnota0 = QGeneric Argument(0), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGArgument =Argument Q5Generic =Argument GenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()) const;

V prípade chyby sa vráti 0.

Ak chcete zavolať metódu, použite invokeMethod() :

static bool QMetaObject::invokeMethod (QObject* obj, const char * člen, typ Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGeneric Argument Q(Generic) =GGeneric QArgument(), QG = QGenericArgument(), QGenericArgument hodnota4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument QArgument = Q(Argument =G) ));
  • obj- ukazovateľ na objekt;
  • členom– názov metódy;
  • typu- typ hovoru:
    • Qt::DirectConnection – okamžite,
    • Qt::QueuedConnection – keď sa QCoreApplication::exec() začne vykonávať,
    • Qt::AutoConnection - synchrónne, ak je objekt v rovnakom vlákne, inak asynchrónne;
  • ret– návratová hodnota;

Pri asynchrónnom volaní sa hodnota nedá vypočítať.

Dochádza k preťaženiu metódy invokeMethod(). Ak nešpecifikujete typ hovoru, použije sa Qt::AutoConnection. Ak nezadáte návratovú hodnotu, bude sa ignorovať.

Trieda QMetaMethod poskytuje rovnaké možnosti:

bool QMetaMethod::invoke (QObject* objekt, Qt::ConnectionType connectionType, QGenericReturnArgument returnValue, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), Q3Generic QArgument val gument (), QGenericArgument val4 = QGenericArgument(), QGenericArgument hodnota5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericGenericArgument val9 = QGenericArgument val9;)

Podobne nemusí byť špecifikovaný typ pripojenia a/alebo návratová hodnota.

Asynchrónne volanie sa používa, keď dokončenie výpočtu trvá príliš dlho, takže jeho výsledok sa v bode volania neočakáva. Takéto výpočty sú zvyčajne umiestnené v samostatnom vlákne, takže štandardne (Qt::AutoConnection) metódy objektov z externých vlákien sa volajú asynchrónne.

Zvážte nasledujúcu triedu:

Výpis 8.1. Trieda MyClass s konštruktorom a metódami dostupnými pre systém metaobjektov
class MyClass: public QObject ( Q_OBJECT public: Q_INVOKABLE MyClass (QString text, QObject *parent = 0); Q_INVOKABLE QString text() const; Q_INVOKABLE void setText (const QString& text); private: QString text_; );

Volanie konštruktora a metód:

Výpis 8.2. Volanie konštruktorov a metód triedy MyClass cez systém metaobjektov
MyClass foo("foo"); const QMetaObject* m_foo = foo.metaObject(); // Vytvorenie novej inštancie: MyClass *bar = qobject_cast (m_foo->newInstance(Q_ARG(QString,"bar"))); if (!bar) ( qCritical()<< "Can"t invoke constructor!"; } else { bar->setParent(&foo); qDebug()<< bar->text(); // "bar" ) // Volanie metódy: if (!QMetaObject::invokeMethod (&foo, "setText", Q_ARG(QString,"baz"))) qCritical()<< "Can"t invoke method!"; QString val; // Вызвать метод и получить возвращенное значение: if (!QMetaObject::invokeMethod (&foo, "text", Q_RETURN_ARG(QString, val))) qCritical() << "Can"t invoke method!"; qDebug() << val; // "baz"

text() a setText() sa nazývajú týmto spôsobom len ako jednoduchý príklad toho, ako funguje QMetaObject::invokeMethod(). Ako už viete, tieto dve metódy musia byť spojené s vlastnosťou.

Všimnite si tiež, že text() vracia QString, ale nie const QString&. Inak by si systém metaobjektov myslel, že text() vracia void .

Záver

Na efektívnu prácu s triedami za behu používa Qt špeciálny objektový model, v ktorom sú pomocou dedenia z QObject a generovania kódu kompilátorom metaobjektov implementované nasledovné:

  • hierarchia objektov;
  • špeciálny analóg dynamic_cast , nezávislý od RTTI;
  • systém signálov a slotov;
  • systém vlastností objektu;
  • dynamická práca s triedami.

V ďalšom článku sa pozrieme na typy, varianty, referencie a rozdelenie dát.

Účelom tejto triedy je poskytnúť informácie o vlastnostiach súboru, napr.: názov, veľkosť, čas poslednej úpravy, oprávnenia atď. Objekt triedy QFileInfo sa vytvorí odovzdaním cesty k súboru jeho konštruktorovi, ale odovzdať možno aj objekty triedy QFile.

Súbor alebo adresár?

Niekedy sa musíte uistiť, že skúmaný objekt je adresár a nie súbor a naopak. Na tento účel existujú metódy isFile() A isDir().

Ak je objektom súbor, metóda isFile() vráti boolovskú hodnotu pravda, inak - falošný. Ak je objektom adresár, potom metóda isDir() vracia pravda, inak - falošný. Okrem týchto metód je trieda QFileInfo obsahuje metódu isSymLink(), vracajúci sa pravda, ak je objektom symbolický odkaz (symbolický odkaz alebo skratka v systéme Windows).

Cesta a názov súboru v Qt

Ak chcete získať cestu k súboru, musíte použiť metódu absolútna cesta k súboru(). Ak chcete získať relatívnu cestu k súboru, mali by ste použiť metódu cesta k súboru(). Ak chcete získať názov súboru, musíte zavolať metódu názov súboru(), ktorý vráti názov súboru spolu s jeho príponou. Ak potrebujete iba názov súboru, mali by ste zavolať metódu baseName(). Ak chcete získať rozšírenie, použite metódu úplná prípona().

Informácie o dátume a čase súboru v Qt

Niekedy potrebujete zistiť čas vytvorenia súboru, čas jeho poslednej úpravy alebo prečítania. Pre túto triedu QFileInfo poskytuje metódy vytvorené(), naposledy zmenené() A lastRead() resp. Tieto metódy vracajú objekty triedy QDateTime, ktorý je možné previesť na reťazec pomocou natiahnuť(). Napríklad:

//Dátum a čas vytvorenia súboru fileInfo.created().toString(); //Dátum a čas poslednej úpravy súboru fileInfo.lastModified().toString(); //Dátum a čas posledného prečítania súboru fileInfo.lastRead().toString();

Získanie atribútov súboru v Qt

Atribúty súboru poskytujú informácie o tom, aké operácie možno so súborom vykonať.

Na ich získanie má trieda QFileInfo nasledujúce metódy:

je čitateľný() - vracia pravda, ak je možné čítať informácie zo zadaného súboru;

isWriteable() - vracia pravda, ak je možné zapísať informácie do určeného súboru;

isHidden() - vracia pravda ak je zadaný súbor skrytý;

isExecutable() - vracia pravda ak je možné spustiť zadaný súbor. V OS UNIX sa to neurčuje na základe prípony súboru, ako sú zvyknutí myslieť programátori v OS DOS a Windows, ale prostredníctvom vlastností samotného súboru.

Určenie veľkosti súboru v Qt

Metóda veľkosť() trieda QFileInf o vráti veľkosť súboru v bajtoch. Veľkosť súborov sa zriedka zobrazuje v bajtoch, častejšie sa na označenie veľkosti používajú špeciálne písmenové symboly. Napríklad pre kilobajt je to písmeno K, pre megabajt je to M, pre gigabajt je to G a pre terabajt je to T. Nasledujúca funkcia vám umožňuje sprevádzať veľkosti písmen aj v rozsahu terabajtov (je dosť možné, že o pár rokov to bude súbor bežnej veľkosti).