Oppl ringsprogram: Skrive Multi Threaded Application i Qt.

Oppl ringsprogram: Skrive Multi Threaded Application i Qt.

Som de fleste GUI-rammer, skjer hendelseshandtering i Qt som standard pa hovedtraden. Dette fungerer bra for sma UI-relaterte endringer, men bryter nar vi ma utfore mer arbeid.

I denne oppl ringen skriver vi et bildekonverteringsprogram som bruker bakgrunnsarbeidertrad for a utfore CPU-intensiv drift, samtidig som GUI-responsen blir responsiv. Vi vil ogsa diskutere prosessEvents og dens fordeler og ulemper, som er forbundet med bakgrunnstrad.

En enkelt gjenget bildeomformer.

Var enkle bildekonverter lar brukeren velge bildefiler, og bruker Qt’s QImage til a endre opplosningen og legge til en liten banner nederst pa hvert bilde. Koden som handterer hvert bilde, er som folger:

Jeg har bygget en liten GUI rundt denne koden som ser noe ut som dette:

Nar en bruker klikker pa & quot; Konverter & quot; knappen kalles folgende kode:

Og for a handtere convertDone-signalet som skjer etter at hver fil er konvertert, har vi folgende funksjon:

Du kan finne full kildekode for dette prosjektet pa Github pa:

Men nar vi kompilerer og kjorer applikasjonen, foles det ikke noe riktig. Bildene konverteres etter hverandre uten noen indikasjon pa GUI. I tillegg er GUI fullstendig frosset under konvertering. Forst etter at sloyfen i ImageConverter ville ende, vil vi kunne fortsette a bruke appen.

Et annet problem oppstar i handleConvertDone-funksjonen. Denne funksjonen skulle ha lagt til «Done» til hver fil etter at den ble konvertert, men den blir ikke kalt for alle filer er konvertert.

I virkelige verden fryser GUIer som dette, er ikke akseptabelt, og vil fore til at brukerne tror at noe er feil eller fast.

Losning 1: Behandle hendelser.

En enkel losning Qt-tilbud er a ringe qApp-> prosessEvent. Qts eventlokke fortsetter a lope og kjore hendelser, selv om var hovedtrad er opptatt. Calling ProcessEvents gir en liten pause i arbeidet vart og lar Qt tomme koenheter. Dette vil tillate litt interaktivitet i programmet uten a legge til flere trader.

For a bruke processEvents kan vi ringe det etter hver filkonvertering for eksempel i sporet som handterer convertDone:

Med denne losningen pa plass vil programmet ta et oyeblikk etter hver fotokonvertering for a handtere alle hendelsene i koen mens konverteringen fant sted. Siden bildet konvertering er relativt rask, vil dette gi brukerne en mye bedre folelse. Denne losningen vil ogsa tillate en bruker a se & quot; Done & quot; lagt til hvert element etter at det ble konvertert.

Men processEvents er sjelden en god losning for denne typen problemer. De fleste bakgrunnsoperasjoner kan ikke lett deles med sma arbeidsstykker, og selv om de kan v re ikke-responsive i tiden mellom biter er det vanligvis ikke akseptabelt.

Losning 2: Legge til Worker Thread.

En bedre losning vil v re a legge til en arbeidstrad som vil utfore bildekonvertering i bakgrunnen, og vil varsle var hovedtrad nar hver fotokonvertering ble gjort.

Qt har et enkelt monster for slike arbeidstakerrader som er ansvarlige for en enkelt oppgave, og vil rapportere tilbake fremgang.

Hver QObject har en tradaffinitet, noe som betyr at QObject er koblet til en bestemt trad. Nar et QObject kreves for a handtere et signal, vil signalbehandleren bli utfort i traden som er koblet til denne QObject.

Som standard er alle vare QObjects koblet til hoved GUI-traden, men det er enkelt a flytte dem rundt til andre arbeidstradstrenger ved a ringe QObject :: moveToThread.

For a legge til en arbeiderrad vil vi:

Opprett en ny QThread i hoved og «flytte» var bilde omformer til den nye traden. Endre hvordan vi kommuniserer med bildeomformeren: I stedet for direkte a kalle dens metoder, bruker vi Qts signaler / slots mekanisme. Qts signaler / slots kontrollerer tradaffiniteten til malet QObject og utforer signalhandtereren i den tilkoblede traden.

I noen tilfeller ma du ogsa legge til et nytt signal for a varsle GUI-traden om at arbeidet er gjort.

Modifikasjonene i koden er derfor:

I filen main.cpp:

I filen mainwindow.cpp:

Legg merke til den siste linjen i den nye konverteringsfunksjonen. Bruke QMetaObject :: invokeMethod forteller Qt a ringe konverteringsmetoden gjennom sine signaler / slotsystem, og ta hensyn til konverterens tradaffinitet. Hadde vi kalt funksjonen direkte, ville den ha blitt henrettet i samme trad, som ikke er det vi onsket.

Alternativt kunne vi ha definert et nytt signal i var MainWindow-klasse og har ImageConverter lytte til signalet.

Full kildekoden for den faste versjonen er tilgjengelig pa github:

Ynon Perek.

Les flere innlegg av denne forfatteren.

Fastsetting Legacy Perl Funksjoner Med Dekoratorer.

Funksjonskunstnere gir oss mulighet til a endre funksjonenes oppforsel uten a endre kilden. Dette er nyttig nar du endrer oppforselen til komplekse eller eldre funksjoner som du ikke vil berore.

En enkel CMake + Qt Widgets Starter Template.

A starte et nytt Qt-prosjekt i Qt-skaperen er en bris takket v re de innebygde malene. Men, hva med de gangene foretrekker du a jobbe fra terminal eller vim? Her er startmalen min for.