You are here
Home > posts

Q_object-spor

Q_object-spor h1>

Qt er basert pa Qt-objektmodellen. Denne arkitekturen er det som gjor Qt kraftig og enkel a bruke. Den er basert pa QObject-klassen og moc-verktoyet.

Ved a avlede klasser fra QObject er en rekke fordeler arvet. De er oppfort nedenfor:

Enkel minnehandtering Signaler og spor Egenskaper Selvkunnskap.

Hver av disse funksjonene er diskutert nedenfor. For du fortsetter er det viktig a huske at Qt er standard C ++ med noen makroer, akkurat som alle andre C / C ++-applikasjoner. Det er ikke noe merkelig eller ikke-standard med det, noe som er ganske godt bevist av det faktum at koden er veldig b rbar.

Enkel minnehandtering.

Nar du oppretter en forekomst av en klasse avledet fra QObject, er det mulig a sende en peker til et overordnet objekt til konstruktoren. Dette er grunnlaget for den forenklede minnestyringen. Nar en forelder er slettet, slettes alle sine barn ogsa. Dette betyr at en klasse avledet fra QObject kan skape forekomster av QObject-barn som passerer dette som foreldre uten a bekymre seg for deres odeleggelse.

For bedre forstaelse folger her og eksempel. Eksempel 2-1 viser var eksempelklasse. Den er avledet fra QObject og rapporterer alt som skjer med det til konsollen. Dette vil gjore det klart hva som skjer nar.

// Et verbose objekt forteller oss hva det gjor hele tiden.

klasse VerboseObject: offentlig QObject.

VerboseObject (QObject * foreldre = 0, char * navn = 0): QObject (foreldre, navn)

For a gjore noe nyttig med klassen, er det nodvendig med en hovedrutine. Det er vist i eksempel 2-2. Legg merke til at det forste som skjer er at en QApplication-forekomst er opprettet. Dette kreves for nesten alle Qt-applikasjoner og er god praksis for a unnga unodvendige problemer. Koden oppretter et minnehierarki vist i figur 2-1.

int main (int argc, char ** argv)

// Opprett et program.

QApplication a (argc, argv);

VerboseObject topp (0, «topp»);

VerboseObject * x = ny VerboseObject (& top, «x»);

VerboseObject * y = nytt VerboseObject (& top, «y»);

VerboseObject * z = ny VerboseObject (x, «z»);

Sorg for a forsta hvordan treet er oversatt til koden fra eksempel 2-2 og omvendt.

Figur 2-1 Minnehukommelsen.

Eksempel 2-3 viser et eksempel pa kjoring av eksempelkoden. Som det kan sees, slettes alle objekter, foreldre forst og deretter chilren. Legg merke til at hver gren er slettet helt for neste startes pa. Dette kan ses som z er slettet for y.

Hvis foreldrehenvisningen er fjernet fra x og y som vist i eksempel 2-4, oppstar en minnelekkasje. Dette er som en provekjoring dokumentert i eksempel 2-5.

VerboseObject * x = nytt VerboseObject (0, «x»);

VerboseObject * y = nytt VerboseObject (0, «y»);

Minnelekkasjen som vises ovenfor, gjor ingen skade i den nav rende situasjonen, ettersom soknaden avsluttes like etter at det har skjedd, men i en annen situasjon kan dette v re en potensiell trussel mot systemstabiliteten.

Signaler og spor.

Signaler og spor er det som gjor de forskjellige Qt-komponentene som gjenbrukbare som de er. De gir en mekanisme der det er mulig a avslore grensesnitt som kan v re fritt sammenkoblet. For eksempel kan et menyelement, trykknapp, verktoylinjeknapp og andre gjenstander eksponere signal som svarer til «aktivert», «klikket» eller en annen passende hendelse. Ved a koble et slikt signal til et spor av noe annet element, henter arrangementet automatisk sporene.

Et signal kan ogsa inkludere verdier, noe som gjor det mulig a koble til en skyveknapp, en spinnboks, en knott eller noe annet verdifrembringende element til et hvilket som helst element som aksepterer verdier, for eksempel en annen skyveknapp, knott eller spinnkasse eller noe helt annet, for eksempel en LCD vise.

Hovedfordelen ved signalene og sporene er at den som ringer ikke trenger a vite noe om mottakeren og omvendt. Dette gjor det mulig a enkelt integrere mange komponenter uten at komponentens designer har tenkt pa den brukte konfigurasjonen. Dette er virkelig los kobling.

Funksjon eller Slot?

For a gjore ting litt komplisert, refererer utviklingsmiljoet levert med Qt 3.1.x og senere noen ganger til spor som funksjoner. Som de oppforer seg pa samme mate, er de fleste tilfeller dette ikke et problem, men i denne teksten vil termen «slot» bli brukt.

For a kunne bruke signalene og sporene ma hver klasse deklareres i en headerfil. Implementeringen er best plassert i en separat cpp-fil. Overskriftsfilen sendes deretter gjennom et Qt-verktoy kalt moc. Moc produserer en cpp som inneholder koden som gjor signalene og sporene skje (og mer). Figur 2-2 illustrerer denne strommen. Legg merke til navngivningskonvensjonen som brukes (moc_-prefikset) i figuren.

Figur 2-2 Moc-strommen.

Denne ekstra kompilering scenen kan virke a komplisere byggeprosessen, men det er enda et Qt verktoy, qmake. Det gjor det sa enkelt som qmake -project & amp; qmake & amp; gjor a bygge noen Qt-applikasjon. Dette vil bli beskrevet i detalj videre i denne oppl ringen.

Hva er signaler og spor – for ekte?

Som nevnt tidligere er en Qt applikasjon 100% C + +, sa hva er signaler og spor for ekte? En del er de faktiske sokeordene, de erstattes ganske enkelt av riktig C + + av forprosessoren. Slots blir deretter implementert som noen klassemedlemmetode mens signaler implementeres av moc. Hvert objekt holder da en liste over sine tilkoblinger (hvilke spor er aktivert av hvilket signal) og dets spor (som brukes til a bygge tilkoblingstabellen i tilkoblingsmetoden. Erkl ringene fra disse tabellene er skjult i Q_OBJECT-makroen. er mer til dette, men alle kan sees ved a se i en moc-generert cpp-fil.

En grunnleggende demonstrasjon av den lose koblingen som signaler og slots gir, er demonstrert i eksemplet nedenfor. Forst er mottaksklassen vist i eksempel 2-6. Legg merke til at ingenting stopper en klasse fra bade mottak og sending, dvs. en enkelt klasse kan ha bade signaler og spor.

klasse mottaker: offentlig QObject.

Mottaker (QObject * foreldre = 0, char * navn = 0): QObject (foreldre, navn)

Denne klassen starter med Q_OBJECT-makroen som er nodvendig hvis andre funksjoner enn den forenklede minnestyringen skal brukes. Denne makroen inneholder noen nokkeldeklarasjoner og tjener som en markor til moc som indikerer at klassen skal analyseres. Legg ogsa merke til at en ny seksjon kalt offentlige spor er lagt til i syntaksen.

Eksemplene 2-7 og 2-8 inneholder implementeringene av sendeklassene. Forste klasse, SenderA, implementerer sendesignalet som sendes ut fra doEmit-medlemmets funksjon. Den andre sendeklassen SenderB sender signaloverforingen fra medlemsfunksjonen doStuff. Legg merke til at disse klassene ikke har noe til felles bortsett fra a arve QObject.

klasse SenderA: offentlig QObject.

SenderA (QObject * foreldre = 0, char * navn = 0): QObject (foreldre, navn)

klasse SenderB: offentlig QObject.

SenderB (QObject * foreldre = 0, char * navn = 0): QObject (foreldre, navn)

avgir (send (5));

tomt overforing (int);

For a demonstrere hvordan moc-koden slas sammen med koden skrevet av de menneskelige programmene, bruker ikke dette eksemplet det klassiske qmake-metoden, men i stedet inneholder koden eksplisitt. For a pakalle moc, brukes folgende kommandolinje: $ QTDIR / bin / moc sisl.cpp -o moc_sisl.h. Den forste linjen i eksempel 2-9 inkluderer den resulterende filen, moc_sisl.h. Eksempelkoden inneholder ogsa koden som lager de forskjellige objektinstansene og kobler de forskjellige signalene og sporene. Dette koden er det eneste stedet som er oppmerksom pa bade mottakerklassen og sendeklassene. Klassene selv kjenner bare signaturen, ogsa kjent som grensesnittet, av signalene som skal sendes eller mottas.

QApplication a (argc, argv);

QObject :: Koble (& sb, SIGNAL (send (int)), & amp; SLOT (fa (int)));

Endelig viser eksempel 2-10 resultatet av en provekjoring. Signalene sendes ut og mottakeren viser verdiene.

Verdier i forbindelsen?

En vanlig misforstaelse er at det er mulig a definere verdiene som skal sendes sammen med et signal nar man foretar forbindelsen, f.eks. Koble til (& SIGNAL (signal (5)), & amp; b, SLOT (spor (int))); . Dette er ikke mulig. Bare signaturene til signalene brukes i tilkoblingssamtalen. Nar du sender ut signalet, kan du fa en parameter, og bare da. Den riktige versjonen av den forrige koden vil v re tilkoblet (& a, SIGNAL (signal (int)), & amp; b, SLOT (spor (int))); og verdien (5) vil bli spesifisert nar du sender ut signalet.

Egenskaper.

Qt-objekter kan ha egenskaper. Disse er bare en verdi som har en type og, i det minste en lesingsfunksjon, men muligens ogsa en skrivefunksjon. Disse brukes for eksempel av Designer for a vise egenskapene til alle widgets. Den offisielle eiendomsdokumentasjonen finner du her.

Egenskaper er ikke bare en fin mate a organisere koden pa og definere hvilken funksjon som pavirker hvilken egenskap. De kan ogsa brukes som en primitiv form for refleksjon. Enhver QObject-peker kan fa tilgang til egenskapene til objektet som er peket pa. Selv om det er en avledet, mer kompleks, klasse.

Koden i eksempel 2-11 viser hvordan en klasse med egenskaper er erkl rt. Den viste koden tilhorer filen propobject.h. Q_PROPERTY makroen i kombinasjon med Q_ENUMS makroen gjor kunsten.

PropObject (QObject * foreldre = 0, char * navn = 0);

TestProperty testProperty () const;

Legg merke til at det ikke er kommaer mellom parametrene til Q_PROPERTY makroen. Syntaxen er den forste typen av eiendommen er deklarert, og deretter folger navnet. Deretter er et nokkelord, enten READ eller WRITE, encoutered og etterfulgt av den tilhorende medlemsfunksjonen.

Les og skriv medlemsfunksjoner.

Det er ikke noe spesielt med lese- og skrivemedlemsfunksjonene. Den eneste begrensningen er at leseren ma v re av parametertypen og ikke ta noen argumenter (dvs. den ma v re av typen tomrom) mens forfatteren ma godta bare ett argument og det ma v re av parametertypen.

Eksempel 2-12 viser koden til propobject.cpp. Dette er implementeringen av eiendomsobjektets klasse.

PropObject :: TestProperty PropObject :: testProperty () const.

Legg merke til at konstruktoren aksepterer QObject-argumentets foreldre og navn. Disse blir viderefort til grunnklassen. Medlemsfunksjonene er bare trivielle implementeringer av en skrivebeskyttet eiendom og en skrivebeskyttet eiendom.

Endelig viser eksempel 2-13 koden til main.cpp. Denne koden far tilgang til egenskapene gjennom standard QObject-grensesnittet i stedet for direkte tilgang. Testkjoringen vist i eksempel 2-14 viser at koden egentlig virker. Legg merke til at enen er vist som den behandles av datamaskinen internt, dvs. som et heltall.

QApplication a (argc, argv);

std :: cout & lt; & lt; o-> eiendom («testProperty») .toString () & lt; & lt; std :: endl;

Selverkjennelse.

Hver Qt-objekt har et meta-objekt. Dette objektet er representert av en forekomst av QMetaObject-klassen. Det brukes til a gi informasjon om dagens klasse. Meta-objektet kan nas gjennom QObject :: metaObject () -funksjonen. Meta-objektet gir noen nyttige funksjoner som er oppfort nedenfor.

Gir navnet pa klassen, f.eks. PropObject i eksemplet fra forrige seksjon.

Gir meta-objektet til superklassen, eller 0 (null) hvis det ikke finnes noen.

Gir navnene pa egenskapene og metadataene for hver eiendom som QMetaProperty.

Gir navnene pa sporene til klassen. Hvis den valgfrie parameteren, super, er satt til sann, er ogsa sporene til superklassene inkludert.

Gir navn pa signalene til klassen. En valgfri parameter, super, er tilgjengelig som for signalnavnet medlemsfunksjon.

Medlemsfunksjonene som er oppfort ovenfor er bare hint. Det er mer meta informasjon tilgjengelig. Se pa den offisielle dokumentasjonen for detaljer.

Kildekoden fra dette kapittelet kan lastes ned herfra.

Top

Hei! Ønsker du å spille i det største kasinoet? Vi fant det for deg. Prøv her nå!