Q_OBJECT मैक्रो क्या करता है? सभी क्यूटी वस्तुओं को इस मैक्रो की आवश्यकता क्यों है?


131

मैंने सिर्फ क्यूटी का उपयोग करना शुरू किया और देखा कि सभी उदाहरण वर्ग परिभाषाओं Q_OBJECTमें पहली पंक्ति के रूप में मैक्रो है । इस प्रीप्रोसेसर मैक्रो का उद्देश्य क्या है?


25
क्यूटी क्विक को संदर्भित करता है और क्यूटी क्यूटी नामक सी ++ लाइब्रेरी को संदर्भित करता है।
ब्लीडोफ

जवाबों:


132

से क्यूटी प्रलेखन :

मेटा-ऑब्जेक्ट कंपाइलर, moc, वह प्रोग्राम है जो Qt के C ++ एक्सटेंशन को हैंडल करता है।

Moc टूल एक C ++ हैडर फ़ाइल पढ़ता है। यदि यह Q_OBJECT मैक्रो वाले एक या अधिक श्रेणी की घोषणाएँ पाता है, तो यह उन वर्गों के लिए मेटा-ऑब्जेक्ट कोड वाले C ++ स्रोत फ़ाइल का उत्पादन करता है। अन्य बातों के अलावा, संकेत और स्लॉट तंत्र, रन-टाइम प्रकार की जानकारी और गतिशील संपत्ति प्रणाली के लिए मेटा-ऑब्जेक्ट कोड आवश्यक है।


मुझे अन्वेषण लिखने की आवश्यकता क्यों नहीं है Q_OBJECT::connect(), बल्कि सिर्फ लिखने की connect()?
mLstudent33

19

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


3
यह भी गलत है कि आपको केवल उन वर्गों पर इसकी आवश्यकता है जो सिग्नल / स्लॉट तंत्र का उपयोग करते हैं। के अभाव Q_OBJECTटूट जाता है qobject_castऔर आत्मनिरीक्षण। यह कुछ खराब व्यवहार को जन्म दे सकता है, इसलिए यह एक बुरा विचार है।
मोनिका

2
यह सच नहीं है कि Q_OBJECTकिसी अन्य (गैर- QObject) कक्षाओं में "चुपचाप" अनदेखा किया जाएगा । सी ++ मानक के अनुसार, यह कई सदस्य कार्यों और चर की घोषणा करके अपरिभाषित व्यवहार का परिचय देता है जो कभी भी परिभाषित नहीं होते हैं। यह आपके वर्ग के नाम स्थान को- QObjectसदस्यों के साथ प्रदूषित भी करता है । उदाहरण के लिए, एक Q_OBJECTअसंबंधित वर्ग को अच्छी तरह से तोड़ सकता है जिसमें एक विधि होती है जिसे कहा जाता है metaObject
मोनिका

2
यह गलत है। यद्यपि आप शायद अधिकांश गिनी-वर्गों को Q_OBJECTमैक्रो से लैस करना चाहते हैं , लेकिन यह मैक्रो के साथ गैर-गिनी-कक्षाओं के साथ-साथ मैक्रो के बिना भी गिनी-कक्षाओं के लिए पूरी तरह से समझ में आता है। मैक्रो उपयोगी है, लेकिन न तो गिनी-कक्षाओं के लिए आवश्यक है और न ही सीमित है।
pasbi

9

MOC (मेटा ऑब्जेक्ट कंपाइलर) Q_OBJECT मैक्रो में शामिल हेडर फ़ाइलों को C ++ समतुल्य स्रोत कोड में परिवर्तित करता है। यह मूल रूप से सिग्नल-स्लॉट तंत्र को नियंत्रित करता है, और इसे C ++ कंपाइलर के लिए समझ में आता है


2
यह गलत है: Q_OBJECTमैक्रो कंपाइलर द्वारा विस्तारित है, इसके लिए मॉक की आवश्यकता नहीं है। मॉक मैक्रो के साथ कुछ भी नहीं करता है, लेकिन यह सदस्य चर और विधियों की परिभाषाएं उत्पन्न करता है जो Q_OBJECTमैक्रो ने घोषित किया है
मोनिका

5

1 मेटा-ऑब्जेक्ट सिस्टम के क्यूटी प्रलेखन से

Moc टूल एक C ++ सोर्स फाइल पढ़ता है। यदि यह Q_OBJECT मैक्रो वाले एक या अधिक श्रेणी की घोषणाएँ पाता है, तो यह एक और C ++ स्रोत फ़ाइल बनाता है जिसमें उन प्रत्येक वर्गों के लिए मेटा-ऑब्जेक्ट कोड होता है। यह जेनरेट की गई सोर्स फाइल या तो # क्लास के सोर्स फाइल में शामिल है या, आमतौर पर, क्लास के कार्यान्वयन के साथ संकलित और लिंक की जाती है।

2 Q_OBJECT के क्यूटी प्रलेखन से

Q_OBJECT मैक्रो को एक वर्ग परिभाषा के निजी अनुभाग में दिखाई देना चाहिए जो अपने स्वयं के संकेतों और स्लॉट की घोषणा करता है या जो Qt की मेटा-ऑब्जेक्ट सिस्टम द्वारा प्रदान की गई अन्य सेवाओं का उपयोग करता है।

3 मॉक के क्यूटी प्रलेखन से

Moc टूल एक C ++ हैडर फ़ाइल पढ़ता है। यदि यह Q_OBJECT मैक्रो वाले एक या अधिक श्रेणी की घोषणाएँ पाता है, तो यह उन वर्गों के लिए मेटा-ऑब्जेक्ट कोड वाले C ++ स्रोत फ़ाइल का उत्पादन करता है। अन्य बातों के अलावा, संकेत और स्लॉट तंत्र, रन-टाइम प्रकार की जानकारी और गतिशील संपत्ति प्रणाली के लिए मेटा-ऑब्जेक्ट कोड आवश्यक है।

4 सिग्नल और स्लॉट के क्यूटी प्रलेखन से

Q_OBJECT मैक्रो को कई सदस्य कार्यों को घोषित करने के लिए प्रीप्रोसेसर द्वारा विस्तारित किया जाता है जो कि मॉक द्वारा कार्यान्वित किए जाते हैं; यदि आपको "LcdNumber के लिए अपरिहार्य संदर्भ" की पंक्तियों के साथ कंपाइलर त्रुटियां मिलती हैं, तो आप संभवतः moc को रन करना या लिंक कमांड में moc आउटपुट को शामिल करना भूल गए हैं।


2

जीसीसी में -Eआप विस्तारित मैक्रोज़ देख सकते हैं। यह वही है जो Q_OBJECTलिनक्स पर gcc में विस्तार करता है। जागरूक रहें, यह प्लेटफॉर्म पर निर्भर हो सकता है और यह क्यूटी के संस्करण के आधार पर बदल सकता है। आप देख सकते हैं कि यह मॉक कंपाइलर के लिए केवल एक टैग नहीं है।

# 11 "mainwindow.hh"
#pragma GCC diagnostic push
# 11 "mainwindow.hh"

# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wsuggest-override"
# 11 "mainwindow.hh"
    static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, cons
t char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private:
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wattributes"
# 11 "mainwindow.hh"
    __attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
# 11 "mainwindow.hh"
#pragma GCC diagnostic pop
# 11 "mainwindow.hh"
    struct QPrivateSignal {};

0

Q_OBJECT मैक्रो को एक वर्ग परिभाषा के निजी अनुभाग में दिखाई देना चाहिए जो अपने स्वयं के संकेतों और स्लॉट की घोषणा करता है या जो Qt की मेटा-ऑब्जेक्ट सिस्टम द्वारा प्रदान की गई अन्य सेवाओं का उपयोग करता है।


1
यह भ्रामक है: Q_OBJECTमैक्रो को हर उस वर्ग में प्रकट होना चाहिए जो इससे प्राप्त होता है QObject। मैक्रो अनुपस्थित होने पर आपका कोड आसानी से टूट जाएगा, और क्योंकि यह संकलन करने के लिए होता है यह ठीक नहीं है।
मोनिका

@ KubaOber आपके पास कोड का एक उदाहरण है जो संकलित करता है लेकिन Q_OBJECTमैक्रो के लापता होने पर काम नहीं करता है?
क्रिस

2
यदि आप के कार्यान्वयन को देखते हैं Q_OBJECT, तो आप पाएंगे कि यह एक्सेस स्पेसियर्स का उपयोग करता है। इसलिए चाहे मैक्रो के तहत में दिखाई देनी चाहिए private, protectedया publicविनिर्देशक अप्रासंगिक है - यह वर्ग के सिर पर यह जगह करने के लिए सिर्फ सम्मेलन है।
ट्रेब्ल्डज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.