Powiedzmy, że mam ten sygnał:
signals:
void progressNotification(int progress);
Dopiero niedawno dowiedziałem się o słowie kluczowym emit w Qt. Do tej pory wykonywałem sygnały, po prostu wywołując je jak zwykłą funkcję. Więc zamiast:
emit progressNotification(1000 * seconds);
Napisałbym:
progressNotification(1000 * seconds);
Nazywanie ich w ten sposób wydawało się działać, a wszystkie połączone sloty zostałyby wykonane, więc czy użycie słowa kluczowego emit powoduje inne zachowanie, czy jest to po prostu cukier składniowy?
emit
nie jest potrzebne. To jednak dziwne, że nauczyłeś się o tymemit
długo po bezpośrednim wywołaniu sygnałów, ponieważ system slotów sygnałowych jest jedną z pierwszych rzeczy, których można się nauczyć o Qt.Odpowiedzi:
emit
to tylko cukier syntaktyczny. Jeśli spojrzysz na wstępnie przetworzone wyjście funkcji, która emituje sygnał, zobaczysz, że poemit
prostu go nie ma.„Magia” dzieje się w wygenerowanym kodzie funkcji emitującej sygnał, na którą można spojrzeć, sprawdzając kod C ++ wygenerowany przez moc.
Na przykład
foo
sygnał bez parametrów generuje tę funkcję składową:A kod
emit foo();
jest wstępnie przetwarzany w prosty sposóbfoo();
emit
jest zdefiniowany wQt/qobjectdefs.h
(w każdym razie w wersji źródłowej typu open source), na przykład:(Definicja ochrony polega na umożliwieniu używania Qt z innymi frameworkami, które mają kolidujące nazwy za pośrednictwem
no_keywords
opcji konfiguracyjnej QMake.)źródło
emit
czegoś, co faktycznie dało więcej niż nic? Uważam, że posiadanie `` cukru syntaktycznego '' w tym przypadku po prostu dezorientuje nowicjusza (lub przynajmniej mnie, gdy byłem początkującym użytkownikiem Qt) - wydaje się, że coś magicznego lub ważnego dzieje się zemit
pseudo-słowem kluczowym, kiedy nic nie robi all - cała magia dzieje się w zwykłej starej funkcji, któramoc
tworzy (moc
jest magią dla sygnałów i gniazd Qt).emit
to niepotrzebna dekoracja, która nic nie robi, ale wydaje się ważna.emit
informuje osobę czytającą wywołanie, że magia ma się wydarzyć (tj. spowoduje to uruchomienie kodu w obiektach tej klasy, o których potencjalnie nigdy nie słyszano, a wywołania te mogą być synchroniczne lub asynchroniczne), co jest całkowicie utracone, jeśli pominiesz słowo kluczowe. Użyj tego. To jest automatyczne dokumentowanie. „Nowicjusze” powinni czytać dokumentację i tutoriale, iemit
jest tam zawsze (w każdym razie w oficjalnych dokumentach). Odkrycie, że możesz po prostu wywołać tę funkcję, powinno nastąpić po „zobaczeniu światła” - w tym momencie nie jesteś już nowicjuszem.emit
słowa kluczowego. Myślę, że wolałbym zastosować konwencję nazewnictwa, jeśli istnieje potrzeba wyjaśnienia, że wywołanie funkcji jest sygnałem.emit
.emit
pseudo-słowa kluczowego było wyjaśnienie, że wywoływany jest sygnał, to konwencja nazewnictwa mogłaby zrobić to samo, bez tajemnica i podobne korzyści. Konwencja nazewnictwa nie może być egzekwowana przez Qt (w rzeczywistościmoc
mogłaby ją wymusić - ale ja też tego nie popieram), ale Qt nie może wymusić użyciaemit
żadnego z nich. I chociaż możesz `` wyłączyć '',emit
jeśli występuje konflikt nazw, nie pomaga to zbytnio, jeśli masz kilka plików źródłowych, które go używają (niepotrzebnie, aby uruchomić).Po 18 miesiącach ... zacząłem od komentarzy pod odpowiedzią @ Mata i szybko kończyło się miejsce. Tak więc odpowiedź.
IMO
emit
nie jest ani cukrem syntaktycznym, ani prostym słowem kluczowym w tym sensieconnect
mechanizmowi rozpoznać, że rzeczywiście jest to elementsignal
aCały system sygnału / szczelin to inny idiom niż proste wywołanie funkcji. Uważam, że wynika to ze wzoru obserwatora. Istnieje również zasadnicza różnica między a
signal
i aslot
: sygnał nie musi być implementowany, podczas gdy gniazdo musi być !Idziesz ulicą i widzisz płonący dom (sygnał). Wybierasz numer 911 ( podłącz sygnał pożaru do gniazda odpowiedzi 911 ). Sygnał był tylko emitowany , natomiast szczelina została zrealizowana przez straż pożarną. Może być nieprecyzyjne, ale masz pomysł. Spójrzmy na przykład OP.
Jakiś obiekt zaplecza wie, jaki postęp został osiągnięty. Więc może po prostu
emit progressNotification(...)
sygnalizować. Do klasy, która wyświetla rzeczywisty pasek postępu, należy odebranie tego sygnału i wykonanie na nim. Ale w jaki sposób widok łączy się z tym sygnałem? Witamy w systemie sygnałów / gniazd Qt. Można teraz wyobrazić sobie klasę menedżera (zwykle pewnego rodzaju widget), która składa się z obiektu widoku i obiektu obliczeniowego danych (oba sąQObjects
), które może wykonaćconnect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)
.Nie wchodźmy w aspekty projektowe klasy menedżera, ale wystarczy powiedzieć, że tutaj świeci system sygnału / gniazda. Mogę skupić się na zaprojektowaniu bardzo czystej architektury dla mojej aplikacji. Nie zawsze, ale często okazuje się, że po prostu emituję sygnały, ale wdrażam sloty .
Jeśli możliwe jest użycie / wywołanie metody sygnału bez jej emitowania , oznacza to , że w pierwszej kolejności nigdy nie potrzebowałeś tej funkcji jako sygnału .
źródło
emit
jest rzeczywiście tylko pustym makrem i czysto opcjonalnym. Nie tak to słowa kluczowesignal
, aslot
które są przetwarzane przez MOC.signal
służy do realizacji funkcji,slot
służy do tworzenia wpisu obiektu meta, tak aby można go było znaleźć za pomocąSLOT(MySlot())
makra lub w QML.emit
jest suggarem syntaktycznym. Nic nigdy nie będzie narzekać, jeśli napiszeszemit i++;
(ale może twoi współpracownicy), a nadal nie możesz się połączyći++
.Druga opcja oznaczałaby, że zawsze wiesz, jaka jest nazwa funkcji i jej parametry oraz że obiekt, do którego ją wysyłasz, jest znany tej konkretnej funkcji. Te dwa przypadki nie zawsze są prawdziwe, więc to są dwie główne przyczyny, dla których stworzono szczeliny i sygnały. „pod maską” mechanizm sygnalizacyjno-szczelinowy to po prostu tabela ze wskazówkami do każdej podłączonej funkcji.
Spójrz także na ten plik PDF, który bardzo jasno wyjaśnia naturę mechanizmu sygnałów i szczelin: http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf
źródło
emit
to tylko nie-op. Ale nawet w tym przypadku czytanie treści pytania powinno było wyjaśnić, więc -1.