Qt5 signaler og slots syntaks

opp stemme 11 nedstemme favoritt Tilkobling av et QML-signal til en vanlig C ++-spor er enkelt: // QML.

QObject :: connect (some_qml_container, SIGNAL (foo ()), some_qobject, SLOT (fooSlot ()); // fungerer!

Men uansett hva jeg prover, kan jeg ikke synes a kunne koble til en C ++ 11 lambda-funksjonsspor. // C ++ 11.

QObject :: connect (some_qml_container, SIGNAL (foo ()), [=] ()); // mislykkes.

Begge forsokene feiler med en funksjons signaturfeil (ingen QObject :: Koble overbelastning kan akseptere disse parameterne). Imidlertid betyr Qt 5 dokumentasjonen at dette bor v re mulig. Dessverre kobler Qt 5 eksempler alltid et C ++-signal til et C ++ lambda-spor: // C ++ 11.

QObject :: connect (some_qml_container, & QMLContainer :: foo, [=] ()); // virker!

Denne syntaksen kan ikke fungere for et QML-signal, da QMLContainer :: foo signaturen ikke er kjent pa kompileringstidspunktet (og erkl rer QMLContainer :: foo for hand beseirer formalet med a bruke QML i utgangspunktet.) Er det jeg prover a gjore det mulig? Hvis ja, hva er riktig syntaks for QObject :: connect call? c ++ qt c + + 11 signaler-slots qt5.

& Emsp; dette sporsmalet ble redigert Mar 25 ’13 kl 21:11 Andy Prowl 87k 14 266 363 spurte Mar 25 ’13 kl 21:08 The Fiddler 1,920 10 19 | 2 svar.

up vote 5 down vote — Akseptert — Akseptert — Akseptert —

Lambdas etc fungerer bare med ny syntaks. Hvis du ikke finner en mate a gi QML-signal som en peker, sa tror jeg det ikke er mulig. I sa fall har du en losning: Lag en dummy signal-routing QObject-underklasse, som bare har signaler, en for hvert QML-signal du trenger a rute. Koble deretter QML-signaler til tilsvarende signaler av en forekomst av denne dummy-klassen, ved hjelp av den gamle koblingssyntaxen. Na har du C ++-signaler du kan bruke med den nye syntaksen, og koble til lambdas. Klassen kan ogsa ha en hjelpemetode, for a automatisere tilkoblinger fra QML til signaler fra klassen, som vil benytte QMetaObject refleksjonsmekanismer og et passende signal navngivningssystem, med samme prinsipp som QMetaObject :: connectSlotsByName bruker. Alternativt kan du bare koble QML-rutersignalforbindelsene, men likevel gjemme dem inne i en metode for ruterklassen. Uprovd.

& Emsp; dette svaret ble redigert Mar 26 ’13 kl 7:59 svarte Mar 25 ’13 kl 21:32 hyde 25.5k 10 70 112 Takk for svaret, dette gir meg en ny retning for a se etter et svar: er det mulig a fa en C ++ pekeren til et QML-signal? Hvis ja, kan jeg binde en std :: -funksjon til signalet og en lambda til sporet. Uheldigvis er speiling av hvert QML-signal til et C ++ QObject (antagelig) en verre design enn a definere bare sporene i QObjects (dvs. old school approach). Det jeg vil gjerne gjore er a unnga a bruke QObjects helt, og dra nytte av de nye Qt 5-grensesnittene (som kanskje eller kanskje ikke er mulig). & Ndash; Fiddler Mar 26 ’13 kl 8:49 Vel, ettersom signal-signalforbindelser skje automatisk, kan det bety at det bare er en ekstra linje med kode, noe som denne linjen etter at QML-viseren er oppgitt: MyQMLSignalRouter qmlSignals (& myQmlView.rootObject ()) ; og bruk deretter qmlSignals i nye stilkoblinger. QML-signalene eksisterer ikke som C ++-funksjoner, de kan ikke (de er dynamiske, C ++ er statisk), sa det er ikke engang teoretisk mulig a fa en direkte metodepeker til, sa langt jeg forstar det. & Ndash; hyde Mar 26 ’13 kl 9:04 Min skepsis for denne tiln rmingen ligger i den stramme koblingen mellom QML-signaler og C ++-koden den introduserer, sa vel som den enkle «superklassen» tiln rming (en klasse for a erkl re alle signaler, overalt). Det lukter darlig! Du har helt riktig at QML-signaler ikke er tilgjengelige for C ++ staticall.

main.cpp: ModelValueReceivers * mvr; mvr = ny ModelValueReceivers (); QQuickView visning; view.setSource (QUrl ((«qrc: ///Main.qml»)); QQuickView loginScreenView; loginScreenView.setSource (QUrl (( «qrc: ///LoginScreen.qml»))); QObject * loginScreen =

y. En dynamisk losning kan imidlertid eksistere: QQuickItem :: metaObject () -> indexOfSignal («foo ()») returnerer riktig indeksen til signalet. AFAICT, VVS for a fa et callable wrapper eksisterer ogsa, men er skjult inne i QtPrivate namespace. Nedtur. & Ndash; The Fiddler Mar 26 ’13 kl 10:07 Na ma du skrive den statiske C ++ koden for a ringe tilkobling for a koble lambdaen. Pa det tidspunktet, med autoconnect, trenger du bare a legge til signalet til ruterklassen ogsa (en linje til .h-fil), hvis det er forste gang du kobler det signalet. Hvis signalnavn ikke er kjent ved kompileringstid, vil du trenge et plassholdersignal i ruterklassen, og to tilkoblinger (dynamisk gammelstilstilkobling fra QML til plasseringssignal, statisk ny stilstilkobling fra det til lambda). Jeg er enig i at det er litt ekkel, men lambdas har fordeler med nedleggelser, og hvis det gjelder koden din, sa vil jeg si ga for det. & Ndash; hyde mar 26 ’13 kl 11:19 1 Etter litt mer overveielse endte jeg med a implementere ganske mye hva du foreslar. Det fungerer, og det holder QML-siden blissfully uvitende om C ++-detaljer (renere og mer testbar). Med litt arbeid kan det v re mulig a lage en polymorf SingalRouter-klasse for a unnga a spesifisere alle sporene pa forhand. Takk! & Ndash; The Fiddler Mar 26 ’13 kl 12:10 | vis 1 mer kommentar opp stemme 2 nedstemning I stedet for a lage lambda-funksjoner pa fluen for a handtere forskjellige signaler, vil du kanskje vurdere a bruke et QSignalMapper til a fange opp signaler og sende dem til en statisk definert spor med et argument som er avhengig av kilde. Funksjonens oppforsel vil da helt avhenge av kilden til det opprinnelige signalet. Avviket med QSignalMapper er at du far informasjon om signalkilden, men du mister de opprinnelige argumentene. Hvis du ikke har rad til a miste de opprinnelige argumentene, eller hvis du ikke kjenner signalkilden (som det er tilfelle med QDBusConnection :: connect () signaler), sa er det ikke veldig fornuftig a bruke en QSignalMapper. hydes eksempel ville kreve litt mer arbeid, men vil tillate deg a implementere en bedre versjon av QSignalMapper hvor du kan legge til informasjon om kildesignalet til argumentene nar du kobler signalet til sporet ditt. QSignalMapper klasse referanse: http://qt-project.org/doc/qt-5.0/qtcore/qsignalmapper.html Eksempel: http://eli.thegreenplace.net/2011/07/09/passing-extra-arguments-to -qt-slots / Her er et eksempel rippling et signal gjennom en QSignalMapper-forekomst som kobler til en topp ApplicationWindow-forekomst med et objektnavn pa «app_window»: for (auto app_window: engine.rootObjects ())

hvis (& quot; app_window & quot;! = app_window- & gt; objectName ())

auto signal_mapper = nytt QSignalMapper (& app);

// for neste arg casting incantation, se http://stackoverflow.com/questions/28465862.

[] (int / * ignoreres i dette tilfellet * /)

& Emsp; dette svaret ble redigert 17. november kl. 19:46 Ross Rogers 9,892 15 64 117 svaret 7 juni ’13 kl 7:31 dmiller309 196 2 5 |

ew-> setSource (QUrl («qrc: /nav.qml»)); ui- & gt; nav-> addWidget (qmlView); Blockschaltbild bild; QObject * verdi = qmlView- & gt; rootObject (); QObject: : Koble til (verdi, SIGNAL (testSig ()), og bilde, SLOT (BlockSlot ())); Signalene og sporene kobles til riktig.

opp stemme 11 nedstemme favoritt Tilkobling av et QML-signal til en vanlig C ++-spor er enkelt: // QML.