यह एक नियमित समारोह में क्यूटी के रूप में एक संकेत के रूप में फोन कर रहा है


97

मान लें कि मेरे पास यह संकेत है:

signals:
    void progressNotification(int progress);

मैंने हाल ही में क्यूटी में एमिट कीवर्ड के बारे में सीखा है। अब तक, मैं संकेतों को केवल एक नियमित फ़ंक्शन की तरह कॉल करके निष्पादित करता था। इसलिए इसके बजाय:

emit progressNotification(1000 * seconds);

मैं लिखूंगा:

progressNotification(1000 * seconds);

उन्हें कॉल करने से ऐसा लगता है कि काम करने के लिए, और सभी जुड़े हुए स्लॉट निष्पादित होंगे, इसलिए एमिट कीवर्ड का उपयोग करने से एक अलग व्यवहार होता है, या क्या यह सिंटैक्टिक चीनी है?


17
+1 कभी नहीं पता था कि emitजरूरत नहीं है। हालांकि यह अजीब है, कि आपने emitसिग्नल को सीधे कॉल करने के बाद लंबे समय तक सीखा , क्योंकि सिग्नल-स्लॉट सिस्टम क्यूटी के बारे में जानने वाली पहली चीजों में से एक है।
क्रिश्चियन राउ

जवाबों:


88

emitबस वाक्य रचना चीनी है। यदि आप फ़ंक्शन के पूर्व-संसाधित आउटपुट को देखते हैं जो सिग्नल का उत्सर्जन करता है, तो आप देखेंगे emitकि बस चला गया है।

"जादू" सिग्नल उत्सर्जक फ़ंक्शन के लिए उत्पन्न कोड में होता है, जिसे आप मॉक द्वारा उत्पन्न C ++ कोड का निरीक्षण करके देख सकते हैं।

उदाहरण के लिए fooकोई पैरामीटर के साथ एक संकेत इस सदस्य समारोह उत्पन्न करता है:

void W::foo()
{
    QMetaObject::activate(this, &staticMetaObject, 0, 0);
}

और कोड emit foo();को पूर्व में संसाधित किया जाता हैfoo();

emitइस तरह से Qt/qobjectdefs.h(स्रोत के खुले स्रोत स्वाद में परिभाषित किया गया है):

#ifndef QT_NO_EMIT
# define emit
#endif

(परिभाषित गार्ड आपको no_keywordsQMake कॉन्फ़िगरेशन विकल्प के माध्यम से नाम टकराने वाले अन्य चौखटे के साथ Qt का उपयोग करने की अनुमति देने के लिए है ।)


14
क्या आप जानते हैं कि क्या वास्तव में कार्यान्वयन (या एक नियोजित कार्यान्वयन) emitथा जो वास्तव में कुछ नहीं से अधिक था? मुझे लगता है कि इस मामले में 'सिंटैक्टिक शुगर' होने से केवल नौसिखिया (या कम से कम मुझे तब होता है जब मैं एक नौसिखिया क्यूटी उपयोगकर्ता था) को भ्रमित करता हूं - यह प्रतीत होता है कि emitछद्म-कीवर्ड के साथ कुछ जादुई या महत्वपूर्ण हो रहा है , जब यह कुछ भी नहीं है सभी - सभी जादू एक नियमित पुराने फ़ंक्शन में होता है जो mocबनाता है ( mocक्यूटी संकेतों और स्लॉट्स के लिए जादू है)। emitअनावश्यक सजावट है जो कुछ भी नहीं करता है लेकिन महत्वपूर्ण लगता है।
माइकल बूर

12
फेंकना है नहीं "सिर्फ सजावट"। emitकॉल पढ़ने वाले व्यक्ति को बताता है कि जादू होने वाला है (यानी यह उन वस्तुओं में कोड को ट्रिगर करने वाला है जो संभवतः इस वर्ग ने कभी नहीं सुने होंगे, और ये कॉल सिंक्रोनस या एसिंक्रोनस हो सकते हैं), जो अनिवार्य रूप से पूरी तरह से खो जाता है यदि आप कीवर्ड को छोड़ देते हैं। इसका इस्तेमाल करें। यह ऑटो-डॉक्यूमेंटिंग है। "नोविस" को डॉक्स और ट्यूटोरियल पढ़ना चाहिए, और emitहमेशा वहाँ (आधिकारिक डॉक्स में वैसे भी) है। यह पता चलता है कि आप फ़ंक्शन को कॉल कर सकते हैं तब होना चाहिए जब आपने "प्रकाश देखा था" - आप उस बिंदु पर किसी भी अधिक नौसिखिया नहीं हैं।
Mat

19
हम्म, मुझे यकीन नहीं है कि मैं इस बात से सहमत हूं कि emit'कीवर्ड' कितना मूल्यवान है। मुझे लगता है कि यदि कोई फ़ंक्शन कॉल एक संकेत है, तो यह स्पष्ट करने की आवश्यकता है कि मैंने नामकरण सम्मेलन का उपयोग किया है।
माइकल बूर

2
ठीक है, मैं इससे बहुत असहमत हूं। :) एक नामकरण सम्मेलन को मजबूर करना कुछ ऐसा है जो आप अपनी परियोजनाओं / कार्यस्थल में खुद कर सकते हैं, क्यूटी इसे रोकता नहीं है। Qt आपको "कीवर्ड" का उपयोग करने के लिए मजबूर नहीं करता है, और यहां तक ​​कि अगर यह आपके कोड के अन्य भागों के साथ टकराता है, तो आपको इसे बंद करने की अनुमति देता है। मेरी राय में, कीवर्ड दृष्टिकोण बेहतर है - संकलक आपको नामकरण नीतियों को लागू करने में मदद नहीं कर सकता है, लेकिन यह एक गलत वर्तनी को पकड़ लेगा emit
Mat

15
स्पष्ट होने के लिए - मैं इस बात की वकालत नहीं कर रहा था कि एक नामकरण सम्मेलन का उपयोग किया जाए - बस अगर एक emitpsuedo- कीवर्ड-टिप्पणी का कारण यह स्पष्ट करना था कि एक संकेत दिया जा रहा है, तो एक नामकरण सम्मेलन ही कर सकता है, नहीं के साथ रहस्य और इसी तरह के लाभों के साथ। नामकरण सम्मेलन Qt द्वारा लागू नहीं किया जा सकता है (वास्तव में, mocइसे लागू कर सकता है - लेकिन मैं या तो इसकी वकालत नहीं कर रहा हूं), लेकिन Qt emitदोनों के उपयोग को लागू नहीं कर सकता है । और जब आप emitनाम बंद कर सकते हैं, तो 'बंद' कर सकते हैं , इससे बहुत मदद नहीं मिलती है अगर आपके पास स्रोत फ़ाइलों का एक गुच्छा है जो इसका उपयोग कर रहे हैं (अनावश्यक रूप से, बूट करने के लिए)।
माइकल बूर

2

18 महीनों के बाद ... मैंने @ मैट के उत्तर के तहत टिप्पणियों के साथ शुरुआत की, और जल्दी से कमरे से बाहर चल रहा था। इस प्रकार उत्तर।

IMO emitन तो सिंटैक्टिक चीनी है और न ही इस अर्थ में एक सरल कीवर्ड है

  1. यह कोड उत्पन्न करता है (जैसा कि ऊपर @ माट द्वारा समझाया गया है),
  2. यह connectतंत्र को पहचानने में मदद करता है कि वास्तव में यह एक है signal, और
  3. यह आपके सिग्नल को एक "बड़ी" प्रणाली का हिस्सा बनाता है, जहां सिग्नल और प्रतिक्रियाएं (स्लॉट) को सिंक्रोनाइज़ या एसिंक्रोनस रूप से निष्पादित किया जा सकता है, या पंक्तिबद्ध किया जा सकता है, यह निर्भर करता है कि सिग्नल कहाँ और कैसे उत्सर्जित हुआ। यह सिग्नल / स्लॉट सिस्टम की एक अत्यंत उपयोगी विशेषता है।

संपूर्ण सिग्नल / स्लॉट सिस्टम एक साधारण फ़ंक्शन कॉल की तुलना में एक अलग मुहावरा है। मेरा मानना ​​है कि यह पर्यवेक्षक पैटर्न से उपजा है। A signalऔर a के बीच एक प्रमुख अंतर भी है slot: एक सिग्नल को लागू करने की आवश्यकता नहीं है , जबकि एक स्लॉट होना चाहिए !

आप सड़क पर चल रहे हैं और आग पर एक घर (एक संकेत) देख रहे हैं। आप 911 डायल करें ( फायर सिग्नल को 911 रिस्पॉन्स स्लॉट से कनेक्ट करें )। संकेत केवल उत्सर्जित किया गया था , जबकि स्लॉट को अग्निशमन विभाग द्वारा लागू किया गया था । हो सकता है कि आप इंप्रेस हों, लेकिन आपको इसका अंदाजा है। आइए ओपी के उदाहरण को देखें।

कुछ बैकएंड ऑब्जेक्ट जानता है कि कितनी प्रगति हुई है। तो यह बस emit progressNotification(...)संकेत कर सकता है। यह उस वर्ग पर निर्भर है जो वास्तविक प्रगति पट्टी प्रदर्शित करता है, इस संकेत को लेने और उस पर अमल करने के लिए। लेकिन दृश्य इस संकेत से कैसे जुड़ता है? Qt के सिग्नल / स्लॉट सिस्टम में आपका स्वागत है। अब एक प्रबंधक वर्ग (आमतौर पर एक प्रकार का एक विजेट) का गर्भ धारण कर सकता है, जिसमें एक दृश्य वस्तु और एक डेटा संगणना वस्तु (दोनों जा रहा है QObjects) शामिल हो सकते हैं connect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)

चलो प्रबंधक वर्ग के डिजाइन पहलुओं में नहीं आते हैं, लेकिन यह कहने के लिए पर्याप्त है कि यह वह जगह है जहां सिग्नल / स्लॉट सिस्टम चमकता है। मैं अपने आवेदन के लिए एक बहुत ही साफ वास्तुकला डिजाइन करने पर ध्यान केंद्रित कर सकता हूं। हमेशा नहीं, लेकिन अक्सर बार, मुझे लगता है कि मैं केवल संकेतों का उत्सर्जन करता हूं लेकिन स्लॉट्स को लागू करता हूं ।

यदि किसी सिग्नल विधि का उपयोग करना / कॉल करना कभी संभव नहीं है , तो यह जरूरी है कि पहली बार सिग्नल के रूप में आपको उस फ़ंक्शन की आवश्यकता न हो


6
नहीं, emitवास्तव में केवल एक खाली मैक्रो और विशुद्ध रूप से वैकल्पिक है। ऐसा नहीं है कि खोजशब्द signalऔर slotजो मॉक द्वारा संसाधित होते हैं। signalफ़ंक्शन के कार्यान्वयन को प्रदान करने के लिए slotउपयोग किया जाता है , इसका उपयोग मेटा ऑब्जेक्ट प्रविष्टि बनाने के लिए किया जाता है , इसलिए यह SLOT(MySlot())मैक्रो या QML के साथ पाया जाता है । emitसंश्लिष्ट शर्करा है। यदि आप लिखते हैं तो कुछ भी कभी भी शिकायत नहीं करेगा emit i++;(लेकिन शायद आपके सहकर्मी) और आप अभी भी कनेक्ट नहीं कर सकते हैं i++
derM

-5

दूसरा विकल्प यह होगा कि आप हमेशा यह जानते हैं कि फ़ंक्शन का नाम और फ़ंक्शन पैरामीटर क्या हैं और आप जिस ऑब्जेक्ट को भेज रहे हैं, वह उस विशेष फ़ंक्शन द्वारा जाना जाता है। वे दो मामले हमेशा सच नहीं होते हैं, इसलिए यह दो मुख्य बातें हैं कि क्यों स्लॉट और सिग्नल बनाए गए हैं। सिग्नल और स्लॉट तंत्र "अंडर-द-हूड" सिर्फ एक टेबल है जो कनेक्टेड प्रत्येक फ़ंक्शन के लिए पॉइंटर्स के साथ है।

इसके अलावा, इस पीडीएफ को देखें जो बहुत स्पष्ट रूप से संकेतों और स्लॉट तंत्र की प्रकृति की व्याख्या करता है: http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf


सिग्नल के नाम और इसके मापदंडों को जानने के लिए दोनों तरीकों की आवश्यकता होती है - आप इसे छोड़ रहे हैं, आप कुछ ऐसा कैसे कर सकते हैं जिसे आप नहीं जानते हैं? दोनों का शब्दार्थ भी समान है, वे एक जैसे हैं।
Mat

1
शायद आप एक डायरेक्ट स्लॉट कॉल के साथ एक सिग्नल कॉल को गड़बड़ कर रहे हैं? लेकिन मुझे यह स्वीकार करना होगा कि मैंने पहली बार प्रश्न शीर्षक के बारे में सोचा था, क्योंकि मुझे कभी नहीं पता emitथा कि यह सिर्फ एक ऑप-ऑप है। लेकिन इस मामले में भी प्रश्न को पढ़ने से शरीर को साफ करना चाहिए, इसलिए -1।
क्रिश्चियन राउ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.