मैं पहले उल्लेख करना चाहता हूं कि निम्नलिखित क्यूटी 5.0.0 बीटा 1 (शायद बीटा 2 और आरसी भी, पता नहीं) तक ठीक काम करता है, लेकिन क्यूटी में विफल रहता है 5.0.0 अंतिम रिलीज संस्करण। मैं केवल क्यूटी 5.0.0 अंतिम रिलीज संस्करण में देखे गए परिणामों का उल्लेख करना चाहता हूं। तो शायद यह Qt5 में हाल के परिवर्तनों के साथ कुछ करने के लिए है।सी ++ का उपयोग करें - क्यूएमएल में स्लॉट जो नामस्थान में टाइप करता है
सी ++ पक्ष पर मेरे पास नामस्थान में कक्षाओं (क्यूओब्जेक्ट-व्युत्पन्न) का एक सेट है (जिसे वैकल्पिक रूप से कंपाइलर झंडे से ट्रिगर किया जाता है; कक्षाएं अलग पुस्तकालय में होती हैं और लाइब्रेरी एक विकल्प के रूप में नामस्थान का उपयोग छोड़ देती है पुस्तकालय का उपयोगकर्ता)। एक वर्ग है, यहाँ Game
, इस (अंश) दिखाई देंगे:
OAE_BEGIN_NAMESPACE
// forward-declarations:
class Player; // Player is just another class in the same library
class Game : public QObject
{
Q_OBJECT
public:
explicit Game(...);
public slots:
Player *player() const; // <-- the quesion is about such slots
};
OAE_END_NAMESPACE
मैक्रो OAE_BEGIN/END_NAMESPACE
के लिए या तो namespace OAE_NAMESPACE {
... }
या कुछ भी नहीं का विस्तार, उसी तरह क्यूटी <qglobal.h>
में यह करता है में, बस "क्यू" की जगह "OAE" मैक्रो नाम के साथ:
#ifndef OAE_NAMESPACE
# define OAE_PREPEND_NAMESPACE(name) ::name
# define OAE_USE_NAMESPACE
# define OAE_BEGIN_NAMESPACE
# define OAE_END_NAMESPACE
# define OAE_BEGIN_INCLUDE_NAMESPACE
# define OAE_END_INCLUDE_NAMESPACE
# define OAE_BEGIN_MOC_NAMESPACE
# define OAE_END_MOC_NAMESPACE
# define OAE_FORWARD_DECLARE_CLASS(name) class name;
# define OAE_FORWARD_DECLARE_STRUCT(name) struct name;
# define OAE_MANGLE_NAMESPACE(name) name
#else /* user namespace */
# define OAE_PREPEND_NAMESPACE(name) ::OAE_NAMESPACE::name
# define OAE_USE_NAMESPACE using namespace ::OAE_NAMESPACE;
# define OAE_BEGIN_NAMESPACE namespace OAE_NAMESPACE {
# define OAE_END_NAMESPACE }
# define OAE_BEGIN_INCLUDE_NAMESPACE }
# define OAE_END_INCLUDE_NAMESPACE namespace OAE_NAMESPACE {
# define OAE_BEGIN_MOC_NAMESPACE OAE_USE_NAMESPACE
# define OAE_END_MOC_NAMESPACE
# define OAE_FORWARD_DECLARE_CLASS(name) \
OAE_BEGIN_NAMESPACE class name; OAE_END_NAMESPACE \
using OAE_PREPEND_NAMESPACE(name);
# define OAE_FORWARD_DECLARE_STRUCT(name) \
OAE_BEGIN_NAMESPACE struct name; OAE_END_NAMESPACE \
using OAE_PREPEND_NAMESPACE(name);
# define OAE_MANGLE_NAMESPACE0(x) x
# define OAE_MANGLE_NAMESPACE1(a, b) a##_##b
# define OAE_MANGLE_NAMESPACE2(a, b) OAE_MANGLE_NAMESPACE1(a,b)
# define OAE_MANGLE_NAMESPACE(name) OAE_MANGLE_NAMESPACE2(\
OAE_MANGLE_NAMESPACE0(name), OAE_MANGLE_NAMESPACE0(OAE_NAMESPACE))
namespace OAE_NAMESPACE {}
# ifndef OAE_BOOTSTRAPPED
# ifndef OAE_NO_USING_NAMESPACE
/*
This expands to a "using OAE_NAMESPACE" also in _header files_.
It is the only way the feature can be used without too much
pain, but if people _really_ do not want it they can add
DEFINES += OAE_NO_USING_NAMESPACE to their .pro files.
*/
OAE_USE_NAMESPACE
# endif
# endif
#endif /* user namespace */
निम्नलिखित में, जब कह मूल्य oae
साथ इस मामले में, मेरा मतलब है मैं मैक्रो OAE_NAMESPACE
घोषणा की, "नाम स्थान को सक्षम करने"।
दूसरों के बीच में, मैं इस कक्षा के उदाहरणों और Player
कक्षा तक पहुंचता हूं जैसा कि player()
द्वारा मेरे आवेदन के उपयोगकर्ता इंटरफ़ेस के लिए QML के भीतर से लौटाया गया है। इस के लिए, मैं वर्गों रजिस्टर इस प्रकार है:
qmlRegisterType<Game>();
qmlRegisterType<Player>();
मैं QML एक Game
का एक उदाहरण के लिए सूचक दृश्यपटल प्रदान करते हैं theGame
QML के भीतर बुलाया:
view.engine()->rootContext()->setContextProperty("theGame",
QVariant::fromValue<Game*>(game));
QML के भीतर, मैं के रूप में उपयोग हमेशा की तरह।
Rectangle {
width: 100; height: 100
Component.onCompleted: console.log(theGame.player())
}
मैं मिल निम्नलिखित परिणाम, कि क्या मैं सेट के आधार पर एक OAE_NAMESPACE
या नहीं (वैसे: मैं एक ही सेटिंग दोनों पुस्तकालय और के लिए उपयोग एक छोटा सा उदाहरण player()
का एक सूचक पता प्रिंट चाहिए आवेदन इसे का उपयोग):
जब नाम स्थान अक्षम करने, सब कुछ उम्मीद के रूप में काम करता है और QML मुझे सूचक प्रिंट:
Player(0x10b4ae0)
जब नाम स्थान को सक्षम करने के लिए (और सी ++ लाइब्रेरी का उपयोग कर कोड में यह
using
, तो मैं बिल्कुल कोड में परिवर्तन नहीं करते), QML करने में विफल रहताGame::player()
की वापसी प्रकार को समझने:Error: Unknown method return type: Player*
जब
oae::Player*
को वापसी प्रकारGame::player()
की बदल रहा है, सब कुछ फिर से ठीक काम करता है:oae::Player(0x10b4ae0)
मेरा निष्कर्ष है कि अब तक moc
नाम स्थान मैं कक्षा के आसपास डाल पर विचार नहीं करता है। मेरा पहला अनुमान था: अरे, moc
पता नहीं है कि मैं जब g++
बुला नाम स्थान को परिभाषित है, जो है जो मैं .pro फ़ाइल में कार्य करें:
DEFINES += OAE_NAMESPACE=oae
हालांकि, जब OAE_NAMESPACE::Player*
में लौटने प्रकार बदल कर, यह अभी भी काम करता है, इसलिए OAE_NAMESPACE
मैक्रो के बारे में पता है, लेकिन यह या तो OAE_BEGIN/END_NAMESPACE
मैक्रोज़ का विस्तार नहीं करता है या यह अब नामस्थानों का विश्लेषण नहीं करता है।
जब नाम स्थान अक्षम और वापसी प्रकार
Player*
का उपयोग कर:moc
Player * Game::player() const
जो विधि की वापसी प्रकार containes निम्नलिखित "stringdata" पैदा करता है"player\0Player*\0"
जब नामस्थान सक्षम करना और वापसी प्रकारका उपयोग करना 0:
"player\0Player*\0"
जब नाम स्थान सक्षम करने और वापसी प्रकार
OAE_NAMESPACE::Player*
का उपयोग कर के रूप में नाम स्थान है, तो साथQMetaObject::className()
द्वारा दिया"player\0oae::Player*\0"
दूसरी ओर, moc
पहले जोड़ता वर्ग के नाम सक्षम होना चाहिए।
मेरा निष्कर्ष है कि मैं अब ClassName
के बजाय OAE_NAMESPACE::ClassName
लेखन जब भी इन प्रकार का उपयोग कर QObject मेटा तरीकों के हस्ताक्षर में करके इसे ठीक कर सकता है। (ठीक है, बेहतर मैक्रो OAE_PREPEND_NAMESPACE
है)। चूंकि यह कोड में भयानक लगेगा, और मेरे लिए यह भी गलत लगता है क्योंकि विधि पहले से ही नामस्थान, में एक बेहतर समाधान है?
अब वहाँ भी OAE_BEGIN/END_MOC_NAMESPACE
(अनुरूप QT_BEGIN/END_MOC_NAMESPACE
के लिए), तो शायद मैं उन कहीं भी की जरूरत है? मुझे नहीं पता कि वे क्यूटी में कहां/कैसे उपयोग किए जाते हैं, इसलिए मुझे उनकी लाइब्रेरी में तदनुसार उनका उपयोग करना चाहिए, क्योंकि मैं क्यूटी के समान वैकल्पिक नामस्थान सुविधा का उपयोग करना चाहता हूं।
मैं किस कोड मॉक का उत्पादन करता हूं (उदाहरण के लिए स्लॉट का हस्ताक्षर कैसे पार्स किया गया था) पर कुछ जानकारी जोड़ देगा। – leemes
qmlRegisterType <> नामस्थान-योग्य टाइपनाम के साथ कुछ भी बदलता है? – mlvljr
@mlvjr आपके संकेत के लिए धन्यवाद, लेकिन मैंने पहले ही यह कोशिश की है। असल में, यह कुछ भी नहीं बदला जाना चाहिए, क्योंकि यह एक सी ++ प्रकार निर्दिष्ट है लेकिन यह है कि 'moc' हेडर फ़ाइल को कैसे पार करता है। यह पता नहीं लगाता है कि नेमस्पेस के भीतर 'प्लेयर' वास्तव में नामस्थान के बाहर उपयोग किए जाने पर कक्षा 'ओए :: प्लेयर' को संदर्भित करता है। इसके अलावा मेरा मानना है कि यह व्यवहार क्यूटी 5.0.0 अल्फा और बीटा 1 में अलग था। – leemes