क्यूटी घटनाओं और संकेत / स्लॉट


97

Qt दुनिया में, घटनाओं और संकेत / स्लॉट्स में क्या अंतर है?

क्या कोई दूसरे की जगह लेता है? क्या घटनाएं सिग्नल / स्लॉट्स का अमूर्त हिस्सा हैं?

जवाबों:


30

क्यूटी प्रलेखन शायद यह सबसे अच्छा बताते हैं:

क्यूटी में, घटनाएं ऑब्जेक्ट हैं, जो अमूर्त QEventवर्ग से ली गई हैं , जो उन चीजों का प्रतिनिधित्व करती हैं जो या तो किसी एप्लिकेशन के भीतर हुई हैं या बाहरी गतिविधि के परिणामस्वरूप जिनके बारे में एप्लिकेशन को पता होना चाहिए। घटनाएँ किसी QObjectउपवर्ग के किसी भी उदाहरण से प्राप्त और नियंत्रित की जा सकती हैं , लेकिन वे विगेट्स के लिए विशेष रूप से प्रासंगिक हैं। यह दस्तावेज़ बताता है कि कैसे घटनाओं को एक विशिष्ट एप्लिकेशन में वितरित और नियंत्रित किया जाता है।

तो घटनाओं और संकेत / स्लॉट एक ही चीजों को पूरा करने वाले दो समानांतर तंत्र हैं। सामान्य तौर पर, एक घटना एक बाहरी संस्था (उदाहरण के लिए, कीबोर्ड या माउस व्हील) द्वारा उत्पन्न की जाएगी और इवेंट लूप के माध्यम से वितरित की जाएगी QApplication। सामान्य तौर पर, जब तक आप कोड सेट नहीं करते, तब तक आप ईवेंट नहीं बना पाएंगे। QObject::installEventFilter()उपयुक्त कार्यों को ओवरराइड करके आप उन्हें उप-वर्गीकृत ऑब्जेक्ट में घटनाओं को फ़िल्टर या संभाल सकते हैं।

सिग्नल और स्लॉट उत्पन्न करना और प्राप्त करना बहुत आसान है और आप किसी भी दो QObjectउपवर्गों को जोड़ सकते हैं । उन्हें मेटाक्लास के माध्यम से नियंत्रित किया जाता है (अधिक के लिए आपकी moc_classname.cpp फ़ाइल पर एक नज़र डालें), लेकिन अधिकांश इंटरक्लास संचार जो आप उत्पन्न करेंगे वे संभवतः सिग्नल और स्लॉट का उपयोग करेंगे। सिग्नल तुरंत या एक कतार के माध्यम से स्थगित हो सकते हैं (यदि आप थ्रेड का उपयोग कर रहे हैं)।

एक संकेत उत्पन्न किया जा सकता है।


आस्थगित कतार कतार घटना लूप के समान है, या यह दो कतार में मौजूद है? घटना के लिए और संकेत के लिए एक?
गुइलूमे

29
@ उत्तर को स्वीकार करने के लिए आप पर शर्म आती है। - उद्धृत पैराग्राफ में शब्द "सिग्नल" या "स्लॉट" भी नहीं है!
राबर्ट सीमर

1
@neuronet: पैराग्राफ के साथ उद्धृत किया गया है "[यह] इसे सबसे अच्छा समझाता है", जो यह नहीं करता है। हर्गिज नहीं। थोड़ा सा भी नहीं।
राबर्ट सीमर

@Robert अगर उस छोटी इंट्रो लाइन को बदल दिया गया तो "पहले आइए विचार करें कि डॉक्स घटनाओं को कैसे समझाते हैं, यह सोचने से पहले कि वे संकेतों से कैसे संबंधित हैं" क्या आप उत्तर के साथ ठीक होंगे? यदि ऐसा है, तो हम इसे बेहतर बनाने के लिए उत्तर को संपादित कर सकते हैं क्योंकि यह एक मामूली बिंदु है और मैं सहमत हूं कि इसे बेहतर तरीके से कहा जा सकता है। [संपादित करें यह एक वास्तविक प्रश्न है: जैसा कि मुझे यकीन नहीं है कि यह बाकी बहुत बेहतर है .... लेकिन सिर्फ इसलिए कि उद्धृत भाग में संकेतों का उल्लेख नहीं किया गया है, अगर यह बाकी वास्तव में अच्छा है, जो कि मैं हूं मान नहीं रहा है ।]
इरिक

4
@neuronet, यदि आप बोली को पूरी तरह से हटा देते हैं तो इससे मेरी आँखों में उत्तर सुधर जाएगा। - यदि आप पूरे उत्तर को हटा देते हैं, तो यह इस पूरे प्रश्नोत्तर को सुधार देगा।
रॉबर्ट सिएमर

152

Qt में, सिग्नल और इवेंट दोनों ऑब्जर्वर पैटर्न के कार्यान्वयन हैं । उनका उपयोग विभिन्न स्थितियों में किया जाता है क्योंकि उनके पास अलग-अलग ताकत और कमजोरियां हैं।

सबसे पहले हम यह परिभाषित करते हैं कि 'Qt घटना' से हमारा क्या अभिप्राय है: Qt वर्ग में एक वर्चुअल फंक्शन, जो आपसे अपेक्षित है कि यदि आप ईवेंट को हैंडल करना चाहते हैं तो आप के बेस क्लास में उसे फिर से लागू कर दें। यह टेम्पलेट विधि पैटर्न से संबंधित है ।

ध्यान दें कि मैंने " हैंडल " शब्द का उपयोग कैसे किया । दरअसल, यहाँ संकेतों और घटनाओं के इरादे के बीच एक बुनियादी अंतर है:

  • आप घटनाओं को " हैंडल " करें
  • आपको " सिग्नल उत्सर्जन" की सूचना मिलती है

अंतर यह है कि जब आप घटना को "हैंडल" करते हैं, तो आप एक व्यवहार के साथ "प्रतिक्रिया" करने की जिम्मेदारी लेते हैं जो कक्षा के बाहर उपयोगी होती है। उदाहरण के लिए, उस ऐप पर विचार करें जिस पर एक बटन है जिस पर एक नंबर है। ऐप को उपयोगकर्ता को बटन पर ध्यान केंद्रित करने और "ऊपर" और "नीचे" कीबोर्ड कुंजियों को दबाकर नंबर बदलने की आवश्यकता है। अन्यथा बटन को सामान्य की तरह कार्य करना चाहिए QPushButton(इसे क्लिक किया जा सकता है, आदि)। क्यूटी में यह आपके स्वयं के पुन: प्रयोज्य "घटक" (उपवर्ग QPushButton) का निर्माण करके किया जाता है , जो पुन: लागू होता है QWidget::keyPressEvent। स्यूडोकोड:

class NumericButton extends QPushButton
    private void addToNumber(int value):
        // ...

    reimplement base.keyPressEvent(QKeyEvent event):
        if(event.key == up)
            this.addToNumber(1)
        else if(event.key == down)
            this.addToNumber(-1)
        else
            base.keyPressEvent(event)

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

  • चूंकि हमने एक आभासी को फिर से लागू किया, इसलिए हमारा कार्यान्वयन स्वचालित रूप से हमारी कक्षा में संक्षिप्त हो गया। यदि क्यूटी के डिजाइनरों ने keyPressEventएक संकेत दिया था , तो हमें यह तय करने की आवश्यकता होगी कि क्या विरासत में मिला QPushButtonया सिर्फ बाहरी रूप से संकेत से जुड़ा था। लेकिन उस बेवकूफ हो सकता है, के बाद से क्यूटी में आप कर रहे हैं हमेशा वारिस के उम्मीद जब एक कस्टम व्यवहार के साथ एक विजेट (अच्छे कारण के लिए - पुनर्प्रयोग / प्रतिरूपकता) लेखन। इसलिए keyPressEventएक घटना बनाकर , वे अपने इरादे को व्यक्त करते हैं जो keyPressEventकार्यक्षमता का सिर्फ एक बुनियादी निर्माण खंड है। यदि यह एक संकेत था, तो यह उपयोगकर्ता-सामना करने वाली चीज़ की तरह दिखाई देगा, जब इसका इरादा नहीं है।
  • चूंकि फ़ंक्शन का बेस-क्लास-कार्यान्वयन उपलब्ध है, इसलिए हम अपने विशेष मामलों (अप और डाउन कीज़) को संभालकर और बाकी को बेस क्लास पर छोड़ते हुए चेन-ऑफ़-जिम्मेदारी पैटर्न को आसानी से लागू करते हैं । आप देख सकते हैं कि यह लगभग असंभव होगा अगर keyPressEventएक संकेत था।

क्यूटी के डिजाइन सुविचारित है - वे हमें बनाया सफलता के गड्ढे में गिर जाते हैं सही काम करने के लिए आसान बना और गलत बात करना बहुत मुश्किल (keyPressEvent एक घटना बनाने के द्वारा) द्वारा।

दूसरी ओर, सबसे सरल उपयोग पर विचार करें QPushButton- बस इसे तत्काल करना और इसे क्लिक करने पर अधिसूचित करना :

button = new QPushButton(this)
connect(button, SIGNAL(clicked()), SLOT(sayHello())

यह स्पष्ट रूप से कक्षा के उपयोगकर्ता द्वारा किया जाना है :

  • अगर हमें QPushButtonहर बार उप-वर्ग करना होता है तो हम चाहते हैं कि हमें एक क्लिक के बारे में सूचित करने के लिए कुछ बटन चाहिए, जिसके लिए बिना किसी अच्छे कारण के बहुत सारे उपवर्गों की आवश्यकता होगी ! एक विजेट जो हमेशा "हैलो वर्ल्ड" दिखाता है, messageboxजब क्लिक किया जाता है तो यह केवल एक ही मामले में उपयोगी होता है - इसलिए यह पूरी तरह से पुन: प्रयोज्य नहीं है। फिर, हमारे पास बाहरी रूप से इसे जोड़कर - सही काम करने के अलावा कोई विकल्प नहीं है।
  • हम कई स्लॉट को कनेक्ट करना चाहते हैं clicked()- या कई सिग्नल को कनेक्ट कर सकते हैं sayHello()। संकेतों के साथ कोई उपद्रव नहीं है। सबक्लासिंग के साथ आपको कुछ क्लास आरेखों को बैठना होगा और जब तक आप एक उपयुक्त डिज़ाइन तय नहीं कर लेते हैं।

ध्यान दें कि एक जगह का QPushButtonउत्सर्जन clicked()इसके mousePressEvent()कार्यान्वयन में है। इसका मतलब यह नहीं है clicked()और mousePressEvent()विनिमेय हैं - बस वे संबंधित हैं।

इसलिए संकेतों और घटनाओं के अलग-अलग उद्देश्य होते हैं (लेकिन इसमें संबंधित हैं कि दोनों आपको कुछ होने की सूचना के लिए "सदस्यता" देते हैं)।


मुझे विचार आता है। घटना प्रति-वर्ग है, एक वर्ग के सभी उदाहरण एक ही प्रतिक्रिया करेंगे, उन सभी को समान QClassName :: घटना कहा जाएगा। लेकिन सिग्नल प्रति-ऑब्जेक्ट है, प्रत्येक ऑब्जेक्ट का अपना अनूठा सिग्नल-स्लॉट कनेक्शन हो सकता है।
9: 炸鱼

39

मुझे अब तक के जवाब पसंद नहीं हैं। - मुझे इस प्रश्न के भाग पर ध्यान केंद्रित करने दें:

क्या घटनाएं सिग्नल / स्लॉट्स का अमूर्त हिस्सा हैं?

संक्षिप्त उत्तर: नहीं। लंबे उत्तर से एक "बेहतर" सवाल उठता है: संकेत और घटनाएं कैसे संबंधित हैं?

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

उस चुनिंदा () कॉल का परिणाम हो सकता है: सॉकेट पर नया डेटा X11 से कनेक्ट होता है, एक पैकेट जिसे हम यूडीपी पोर्ट पर सुनते हैं, आदि - आदि। वह सामान न तो क्यूटी सिग्नल है, न ही क्यूटी इवेंट, और Qt मुख्य लूप स्वयं तय करता है यदि यह ताजा डेटा को एक, दूसरे में बदल देता है या इसे अनदेखा करता है।

क्यूटी एक विधि (या कई) को keyPressEvent () की तरह कह सकता है, प्रभावी रूप से एक क्यूटी घटना में बदल सकता है। या क्यूटी एक सिग्नल का उत्सर्जन करता है, जो वास्तव में उस सिग्नल के लिए पंजीकृत सभी कार्यों को देखता है, और उन्हें एक के बाद एक कॉल करता है।

उन दो अवधारणाओं का एक अंतर यहां दिखाई दे रहा है: एक स्लॉट में इस बात का कोई वोट नहीं है कि उस सिग्नल पर पंजीकृत अन्य स्लॉट को कॉल किया जाएगा या नहीं। - इवेंट एक चेन की तरह अधिक होते हैं, और ईवेंट हैंडलर यह तय करता है कि यह उस चेन को बाधित करता है या नहीं। संकेत इस संबंध में एक तारे या पेड़ की तरह दिखते हैं।

एक घटना ट्रिगर हो सकती है या पूरी तरह से एक संकेत में बदल सकती है (सिर्फ एक का उत्सर्जन करें, और "सुपर ()") को कॉल न करें। एक संकेत को एक घटना में बदल दिया जा सकता है (एक घटना हैंडलर को कॉल करें)।

क्या सार मामले पर निर्भर करता है: क्लिक किया गया () - सिग्नल एब्स्ट्रैक्ट माउस इवेंट (एक बटन नीचे और ऊपर फिर से बहुत अधिक घूमने के बिना)। कीबोर्ड इवेंट निचले स्तर से सार होते हैं (या é जैसी चीजें मेरे सिस्टम पर कई महत्वपूर्ण स्ट्रोक हैं)।

हो सकता है कि ध्यान केंद्रित () विपरीत का एक उदाहरण है: यह क्लिक किया गया () सिग्नल का उपयोग कर सकता है (और इस प्रकार सार), लेकिन मुझे नहीं पता कि यह वास्तव में करता है या नहीं।


4
मुझे यह भाग मिलता है: "एक स्लॉट में इस बात का कोई वोट नहीं होता है कि उस सिग्नल पर पंजीकृत अन्य स्लॉट्स को फोन किया जाएगा या नहीं" संकेतों और घटनाओं के बीच अंतर के लिए बहुत ज्ञानवर्धक है। हालाँकि, मेरे पास एक संबंधित प्रश्न है: संदेश क्या हैं और संदेश संकेतों और घटनाओं से कैसे संबंधित हैं? (यदि वे संबंधित हैं)। क्या संदेश संकेतों और घटनाओं के लिए एक अमूर्तता है? क्या उन्हें QObjects (या अन्य वस्तुओं?) के बीच ऐसी बातचीत का वर्णन करने के लिए इस्तेमाल किया जा सकता है?
user1284631

@axeoth: Qt में, "संदेश" जैसी कोई चीज नहीं है। खैर, एक संदेश बॉक्स है, लेकिन इसके बारे में है।
मोनिका

@ कुबाओबर: धन्यवाद। मैं "घटनाओं" का अर्थ था।
user1284631

3
@axeoth: फिर आपका प्रश्न बकवास है। यह पढ़ता है: "क्या घटनाएं हैं और सिग्नल और घटनाओं से संबंधित घटनाएं कैसे हैं"।
मोनिका से

@ कुबाओबर: मुझे एक साल बाद संदर्भ याद नहीं है। वैसे भी, ऐसा लगता है कि मैं लगभग ओपी के रूप में एक ही बात पूछ रहा था: क्या अंतर betwee, घटनाओं और कैसे घटनाओं संकेतों और स्लॉट से संबंधित हैं। क्या वास्तव में मामला वापस था, तो IIRC, मैं कुछ प्रकार के गैर-क्यूटी वर्गों में क्यूटी सिग्नल / स्लॉट-संचालित कक्षाओं को लपेटने के लिए एक रास्ता तलाश रहा था, इसलिए मैं बाद के अंदर से पहले को कमांड करने के लिए किसी तरह देख रहा था। मुझे लगता है कि मैं उन्हें घटनाओं को भेजने पर विचार कर रहा था, इसका मतलब है कि मुझे केवल क्यूटी हेडर शामिल करना था, और संकेत / स्लॉट को लागू करने के लिए अपनी कक्षाओं को मजबूर नहीं करना था।
user1284631

16

इवेंट लूप द्वारा ईवेंट भेजे जाते हैं। प्रत्येक GUI प्रोग्राम को एक इवेंट लूप की आवश्यकता होती है, जो भी आप इसे Qt, Win32 या किसी अन्य GUI लाइब्रेरी का उपयोग करके विंडोज या लिनक्स लिखते हैं। साथ ही प्रत्येक थ्रेड का अपना ईवेंट लूप होता है। Qt में "GUI इवेंट लूप" (जो सभी Qt अनुप्रयोगों का मुख्य लूप है) छिपा हुआ है, लेकिन आप इसे कॉल करना शुरू करते हैं:

QApplication a(argc, argv);
return a.exec();

आपके कार्यक्रम के लिए भेजे गए संदेश OS और अन्य एप्लिकेशन ईवेंट के रूप में भेजे जाते हैं।

सिग्नल और स्लॉट क्यूटी तंत्र हैं। मॉक (मेटा-ऑब्जेक्ट कंपाइलर) का उपयोग करके संकलन की प्रक्रिया में, उन्हें कॉलबैक फ़ंक्शन में बदल दिया जाता है।

घटना में एक रिसीवर होना चाहिए, जो इसे भेजना चाहिए। किसी और को वह घटना नहीं मिलनी चाहिए।

उत्सर्जित सिग्नल से जुड़े सभी स्लॉट निष्पादित किए जाएंगे।

आपको सिग्नल के बारे में घटनाओं के रूप में नहीं सोचना चाहिए, क्योंकि जैसा कि आप क्यूटी प्रलेखन में पढ़ सकते हैं:

जब एक सिग्नल उत्सर्जित होता है, तो इससे जुड़े स्लॉट्स को सामान्य फ़ंक्शन कॉल की तरह, तुरंत निष्पादित किया जाता है। जब ऐसा होता है, सिग्नल और स्लॉट तंत्र किसी भी GUI इवेंट लूप से पूरी तरह से स्वतंत्र होते हैं।

जब आप कोई ईवेंट भेजते हैं, तो उसे कुछ समय तक इंतजार करना चाहिए जब तक कि ईवेंट लूप उन सभी ईवेंट को न भेज दे जो पहले आए थे। इस वजह से, ईवेंट या सिग्नल भेजने के बाद कोड का निष्पादन अलग है। किसी घटना को भेजने के बाद कोड तुरंत चलाया जाएगा। सिग्नल और स्लॉट तंत्र के साथ यह कनेक्शन प्रकार पर निर्भर करता है। आम तौर पर सभी स्लॉट्स के बाद इसे निष्पादित किया जाएगा। Qt का उपयोग करना: QueuedConnection, इसे घटनाओं की तरह ही तुरंत निष्पादित किया जाएगा। Qt प्रलेखन में सभी कनेक्शन प्रकारों की जाँच करें ।


यह वाक्य मुझे Qt सिग्नल-स्लॉट और घटनाओं के बीच भिन्न की संक्षिप्त समझ देता है:When you send an event, it must wait for time when event loop dispatch all events that came earlier. Because of this, execution of the cod after sending event or signal is different
swdev

7

एक लेख है जो कुछ विस्तार से घटना प्रसंस्करण पर चर्चा करता है: http://www.packtpub.com/article/events-and-signals

यह यहां घटनाओं और संकेतों के बीच अंतर पर चर्चा करता है:

घटनाएँ और संकेत एक ही चीज़ को पूरा करने के लिए उपयोग किए जाने वाले दो समानांतर तंत्र हैं। सामान्य अंतर के रूप में, विजेट का उपयोग करते समय सिग्नल उपयोगी होते हैं, जबकि विजेट को लागू करते समय घटनाएं उपयोगी होती हैं। उदाहरण के लिए, जब हम QPushButton जैसे विजेट का उपयोग कर रहे हैं, तो हम निम्न-स्तरीय माउस प्रेस या कुंजी प्रेस घटनाओं की तुलना में इसके क्लिक किए गए () सिग्नल में अधिक रुचि रखते हैं जिसके कारण सिग्नल उत्सर्जित होता है। लेकिन अगर हम QPushButton वर्ग को लागू कर रहे हैं, तो हम माउस और प्रमुख घटनाओं के लिए कोड के कार्यान्वयन में अधिक रुचि रखते हैं। इसके अलावा, हम आमतौर पर घटनाओं को संभालते हैं लेकिन सिग्नल उत्सर्जन से अधिसूचित होते हैं।

यह इसके बारे में बात करने का एक सामान्य तरीका प्रतीत होता है, क्योंकि स्वीकृत उत्तर कुछ समान वाक्यांशों का उपयोग करता है।


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


मैं यह नहीं देख सकता कि एक ही चीज़ को पूरा करने के लिए वे दो तंत्रों का उपयोग कैसे करेंगे - मुझे लगता है कि यह एक बेकार सामान्यीकरण है जो बिना किसी की मदद करता है।
मोनिका

@ KubaOber नहीं यह निचले स्तर के विवरण से बचने में मदद करता है। क्या आप कहेंगे कि पायथन मददगार नहीं है क्योंकि आप मशीन कोड में वही काम कर सकते हैं? :)
एरिक

2
मैं कह रहा हूं कि बोली का पहला वाक्य अब तक सामान्य हो रहा है क्योंकि यह बेकार है। तकनीकी रूप से यह गलत नहीं है, लेकिन केवल इसलिए कि आप चाहें तो ऐसा कर सकते हैं कि सिग्नल-स्लॉट तंत्र क्या करता है, और इसके विपरीत करने के लिए इवेंट पासिंग का उपयोग करें। यह बहुत बोझिल होगा। तो, नहीं, सिग्नल-स्लॉट घटनाओं के समान नहीं हैं , वे एक ही चीज को पूरा नहीं करते हैं , और यह तथ्य कि दोनों मौजूद हैं क्यूटी की सफलता के लिए महत्वपूर्ण है। बटन उदाहरण का संकेत सिग्नल-स्लॉट सिस्टम की सामान्य कार्यक्षमता को पूरी तरह से अनदेखा करता है।
मोनिका

1
"घटनाएँ और संकेत दो समानांतर तंत्र हैं जो एक ही चीज़ को कुछ UI विजेट्स / नियंत्रणों के संकीर्ण दायरे में पूरा करने के लिए उपयोग किए जाते हैं ।" बोल्ड भाग गंभीर रूप से गायब है और उद्धरण को अनसुना कर देता है। फिर भी, कोई यह सवाल कर सकता है कि वास्तव में "समान चीज़" कितनी पूरी होती है: सिग्नल आपको विजेट पर ईवेंट फ़िल्टर स्थापित करने (या विजेट से प्राप्त) के बिना घटनाओं पर क्लिक करने के लिए प्रतिक्रिया देते हैं। संकेतों के बिना इसे करना अधिक बोझिल है और नियंत्रण के लिए ग्राहक कोड को कसकर जोड़े। यह खराब डिजाइन है।
मोनिका

1
घटनाएँ एक सर्वव्यापी अवधारणा है । क्यूटी में विशेष कार्यान्वयन वस्तुतः उन्हें सेट के रूप में डेटा संरचनाओं के लिए पारित किया event। सिग्नल और स्लॉट, समवर्ती , तरीके हैं, जबकि कनेक्शन तंत्र एक डेटा संरचना है जो सिग्नल को एक या अधिक स्लॉट को सूचीबद्ध करने की अनुमति देता है। मुझे आशा है कि आप देखते हैं कि कुछ "सबसेट" या घटनाओं के "संस्करण" के रूप में संकेत / स्लॉट्स की बात करना बकवास है, और इसके विपरीत। वे वास्तव में अलग अलग चीजें हैं जो कर रहे हैं ऐसा कुछ विगेट्स के संदर्भ में समान छोर तक इस्तेमाल किया जा रहा। बस। जितना अधिक आप सामान्य करते हैं, उतना कम सहायक आप IMHO बन जाते हैं।
मोनिका

5

टीएल; डीआर: सिग्नल और स्लॉट अप्रत्यक्ष विधि कॉल हैं। घटनाएँ डेटा संरचनाएँ हैं। इसलिए वे काफी अलग जानवर हैं।

एकमात्र समय जब वे एक साथ आते हैं, जब स्लॉट कॉल थ्रेड सीमाओं के पार किए जाते हैं। स्लॉट कॉल तर्क को डेटा संरचना में पैक किया जाता है और एक कार्यक्रम के रूप में प्राप्त होने वाले धागे की घटना कतार में भेज दिया जाता है। प्राप्त करने वाले थ्रेड में, QObject::eventविधि तर्कों को अनपैक करती है, कॉल निष्पादित करती है, और संभवत: परिणाम रोकती है यदि यह एक अवरुद्ध कनेक्शन था।

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


2

घटनाएँ (उपयोगकर्ता / नेटवर्क इंटरैक्शन के एक सामान्य अर्थ में) आमतौर पर क्यूटी में सिग्नल / स्लॉट के साथ नियंत्रित की जाती हैं, लेकिन सिग्नल / स्लॉट अन्य बहुत सारे काम कर सकते हैं।

QEvent और उसके उपवर्ग मूल रूप से आपके कोड के साथ संवाद करने के लिए फ्रेमवर्क के लिए थोड़े मानकीकृत डेटा पैकेज हैं। यदि आप किसी तरह से माउस पर ध्यान देना चाहते हैं, तो आपको केवल QMouseEvent API को देखना होगा, और लाइब्रेरी डिजाइनरों को हर बार पहिया को सुदृढ़ करने की आवश्यकता नहीं है, जब आपको यह पता लगाना होगा कि माउस ने किसी कोने में क्या किया है। क्यूटी एपीआई।

यह सच है कि यदि आप किसी प्रकार की घटनाओं (फिर से सामान्य स्थिति में) की प्रतीक्षा कर रहे हैं, तो आपका स्लॉट एक तर्क के रूप में QEvent उपवर्ग को लगभग निश्चित रूप से स्वीकार करेगा।

उस कहा के साथ, संकेत और स्लॉट निश्चित रूप से QEvents के बिना उपयोग किया जा सकता है, हालांकि आप पाएंगे कि सिग्नल को सक्रिय करने के लिए मूल प्रेरणा अक्सर किसी प्रकार की उपयोगकर्ता सहभागिता या अन्य अतुल्यकालिक गतिविधि होगी। कभी-कभी, हालांकि, आपका कोड बस एक बिंदु तक पहुंच जाएगा, जहां एक निश्चित सिग्नल को बंद करना सही काम होगा। उदाहरण के लिए, एक लंबी प्रक्रिया के दौरान एक प्रगति बार से जुड़े सिग्नल को बंद करने से उस बिंदु पर QEvent शामिल नहीं होता है।


2
"घटनाओं को आमतौर पर क्यूटी में संकेतों / स्लॉट्स के साथ संभाला जाता है" - वास्तव में नहीं ... QEvent ऑब्जेक्ट हमेशा ओवरलोडेड वर्चुअल के माध्यम से पास होते हैं! उदाहरण के लिए, QWidget में कोई सिग्नल "कीडाउन" नहीं है - इसके बजाय, कीडाउन एक वर्चुअल फ़ंक्शन है।
स्टीफन मोनोव

स्टीफन के साथ सहमत हूँ, वास्तव में Qt का एक बहुत भ्रामक टुकड़ा
हैराल्ड स्चिरिच

1
@Stefan: मैं तर्क दूंगा कि कुछ पर्याप्त Qt ऐप्स कीडाउन को ओवरराइड करते हैं (और इसके बजाय ज्यादातर QAbstractButton :: क्लिक किए गए और QLineEdit :: editingFinished जैसे संकेतों का उपयोग करते हैं) "आमतौर पर" सही ठहराने के लिए। मैं निश्चित रूप से पहले कीबोर्ड इनपुट स्नैग कर चुका हूं, लेकिन यह घटनाओं को संभालने का सामान्य तरीका नहीं है।
जेकरियन

आपके संपादन के बाद ("घटना" से आपका क्या मतलब है) स्पष्ट करते हुए, अब आपका पोस्ट सही है। मैं वैसे शब्दों का पुन: उपयोग करने से बचता हूं, हालांकि। सिग्नल "एक प्रकार की घटनाओं" को बुलाए बिना चीजें काफी खराब हो जाती हैं।
स्टीफन मोनोव

2

लेव वे खेंग द्वारा 'इवेंट प्रोसेसिंग' पढ़ते हुए मुझे यह सवाल मिला । यह भी कहता है:

यहां छवि विवरण दर्ज करें

जैस्मिन ब्लैंचेट कहती हैं:

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


1

एक और मामूली व्यावहारिक विचार: संकेतों को छोड़ने या प्राप्त करने के लिए विरासत की आवश्यकता होती है, QObjectजबकि किसी भी विरासत की वस्तु एक घटना पोस्ट या भेज सकती है (क्योंकि आप इसे लागू करते हैं QCoreApplication.sendEvent()या postEvent()) यह आमतौर पर एक मुद्दा नहीं है: लेकिन संकेतों का उपयोग करने के लिए PyQt को अजीब तरह QObjectसे पहले सुपर क्लास होने की आवश्यकता होती है, और आप केवल संकेत भेजने में सक्षम होने के लिए अपने वंशानुक्रम क्रम को पुनर्व्यवस्थित नहीं करना चाहते हैं। "


-1

मेरी राय में घटनाएँ पूरी तरह से बेमानी हैं और उन्हें बाहर निकाला जा सकता है। ऐसा कोई कारण नहीं है कि संकेतों को घटनाओं या संकेतों द्वारा प्रतिस्थापित नहीं किया जा सकता है, सिवाय इसके कि क्यूटी पहले से ही सेट है जैसा कि है। कतारबद्ध संकेतों को घटनाओं द्वारा लपेटा जाता है और घटनाओं को संकेतों द्वारा लिपटा जा सकता है, उदाहरण के लिए:

connect(this, &MyItem::mouseMove, [this](QMouseEvent*){});

(लेकिन अब में नहीं) में mouseMoveEvent()पाए गए सुविधा फ़ंक्शन को बदल देगा और उन संकेतों को संभाल लेगा जो एक दृश्य प्रबंधक आइटम के लिए उत्सर्जित करेगा। तथ्य यह है कि कुछ बाहरी इकाई द्वारा आइटम की ओर से संकेत उत्सर्जित होता है और क्यूटी घटकों की दुनिया में अक्सर होता है, भले ही इसकी अनुमति नहीं है (क्यूटी घटक अक्सर इस नियम को दरकिनार करते हैं)। लेकिन Qt पुराने कोड के टूटने के डर से कई अलग-अलग डिज़ाइन के फैसलों का एक समूह है और बहुत अधिक पत्थर में डाली जाती है (जो अक्सर किसी भी तरह होता है)।QWidgetQQuickItemmouseMove


QObjectजब आवश्यक हो, तो माता-पिता-बच्चे पदानुक्रम को प्रचारित करने के लिए घटनाओं का लाभ होता है। सिग्नल / स्लॉट कनेक्शन एक फ़ंक्शन को कॉल करने का एक वादा है, सीधे या परोक्ष रूप से, जब एक निश्चित शर्त पूरी होती है। सिग्नल और स्लॉट के साथ संबद्ध हैंडलिंग पदानुक्रम नहीं है।
बेनामी

आप संकेतों के साथ समान प्रचार नियम लागू कर सकते हैं। कोई नियम नहीं है। कि एक निश्चित संकेत को किसी अन्य वस्तु (बच्चे) के लिए फिर से जारी नहीं किया जा सकता है। आप acceptedएक सिग्नल के लिए एक संदर्भ पैरामीटर और इसे संभालने वाले स्लॉट्स जोड़ सकते हैं या आपके पास acceptedफ़ील्ड के साथ संदर्भ पैरामीटर के रूप में एक संरचना हो सकती है । लेकिन क्यूटी ने इसे बनाया डिजाइन विकल्प बनाया और वे अब पत्थर में सेट हैं।
user1095108

1
आप मूल रूप से घटनाओं को फिर से लागू कर रहे हैं यदि आप इसे वैसे ही करते हैं जैसे आप सुझाव देते हैं।
फैबियो ए।

@FabioA। यह ओपी के सवाल का बिंदु है। घटनाएँ और संकेत एक दूसरे को बदल सकते हैं।
user1095108

यदि आपकी ईवेंट पुन: कार्यान्वित होती हैं, तो आप ईवेंट को प्रतिस्थापित नहीं कर रहे हैं। इससे अधिक: घटनाओं के शीर्ष पर संकेतों को लागू किया जाता है । संभवतः आपको किसी अन्य इवेंट लूप को बताने के लिए "इवेंट सिस्टम" की आवश्यकता होती है, संभवतः एक थ्रेड में जो आपका नहीं है, कि भविष्य में कभी-कभी इसे किसी दिए गए फ़ंक्शन को निष्पादित करना होगा।
फैबियो ए।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.