2010-03-15 16 views
8

के साथ क्यूटी सिग्नल के लिए आर्किटेक्चर मैं क्यूटी का उपयोग कर एक वैज्ञानिक डेटा अधिग्रहण अनुप्रयोग विकसित कर रहा हूं। चूंकि मैं क्यूटी में गहरी विशेषज्ञ नहीं हूं, इसलिए मुझे कुछ समस्याएं निम्नलिखित समस्या पर समुदाय से सलाह देनी चाहिए:उप-वर्ग-विशिष्ट, टेम्पलेटेड तर्क प्रकार

एप्लिकेशन कई हार्डवेयर अधिग्रहण इंटरफेस का समर्थन करता है लेकिन मैं उन लोगों के ऊपर एक सामान्य एपीआई प्रदान करना चाहता हूं इंटरफेस। प्रत्येक इंटरफ़ेस में नमूना डेटा प्रकार और इसके डेटा के लिए एक इकाई होती है। इसलिए मैं बूस्ट के std::vector के रूप में प्रत्येक डिवाइस से नमूने के एक वेक्टर का प्रतिनिधित्व कर रहा हूं। इकाइयों की मात्रा (यानी std::vector<boost::units::quantity<unit,sample_type> >)। मैं एक बहु-कलाकार शैली वास्तुकला का उपयोग करना चाहता हूं, जहां प्रत्येक डेटा स्रोत नए प्राप्त डेटा को 1 या अधिक इच्छुक पार्टियों तक प्रसारित करता है। क्यूटी के सिग्नल/स्लॉट तंत्र इस शैली के लिए एक स्पष्ट फिट है। इसलिए, मैं प्रत्येक डेटा स्रोत को

इकाई के लिए और उस डिवाइस के लिए sample_type के लिए सिग्नल उत्सर्जित करना चाहता हूं। चूंकि tempalted QObject उप-वर्ग मेटा-ऑब्जेक्ट कंपाइलर द्वारा समर्थित नहीं हैं, इसलिए samplesAcquired सिग्नल को परिभाषित करने वाले सभी डेटा स्रोतों के लिए एक (tempalted) बेस क्लास होने का कोई तरीका प्रतीत नहीं होता है। दूसरे शब्दों में, निम्नलिखित नहीं होगा काम:

template<T,U> //sample type and units 
class DataSource : public QObject { 
    Q_OBJECT 
    ... 
    public: 
    typedef std::vector<boost::units::quantity<U,T> > SampleVector 
    signals: 
    void samplesAcquired(SampleVector sampleVector); 
}; 

सबसे अच्छा विकल्प मैं साथ आने के लिए कर लिया है एक दो परतों वाले दृष्टिकोण है:

template<T,U> //sample type and units 
class IAcquiredSamples { 
    public: 
     typedef std::vector<boost::units::quantity<U,T> > SampleVector 
     virtual shared_ptr<SampleVector> acquiredData(TimeStamp ts, unsigned long nsamples); 
}; 

class DataSource : public QObject { 
    ... 
    signals: 
     void samplesAcquired(TimeStamp ts, unsigned long nsamples); 
}; 

samplesAcquired संकेत अब अधिग्रहण के लिए टाइमस्टैम्प और नमूने की संख्या देता है और ग्राहकों को उन नमूने को पुनर्प्राप्त करने के लिए IAcquiredSamples API का उपयोग करना होगा। स्पष्ट रूप से डेटा स्रोतों को डेटासोर्स और IAcquiredSamples दोनों को उप-वर्ग करना होगा।

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

एक अन्य संभावना, QVariant तर्क का उपयोग करना है। यह अनिवार्य रूप से उप-वर्ग पर अपने विशेष नमूना वेक्टर प्रकार को Q_REGISTER_METATYPE/qRegisterMetaType के साथ पंजीकृत करने के लिए रखता है। वास्तव में एक बड़ा सौदा नहीं है। हालांकि, बेस क्लास के ग्राहकों को यह जानने का कोई तरीका नहीं होगा कि QVariant मूल्य प्रकार किस प्रकार है, जब तक कि टैग स्ट्रक्चर सिग्नल के साथ भी पास न हो जाए। मैं इस समाधान को कम से कम एक के रूप में समेकित मानता हूं, क्योंकि यह सार प्रणाली के कुछ गहन पहलुओं से निपटने के लिए अमूर्त बेस क्लास एपीआई के ग्राहकों को मजबूर करता है।

तो, क्या टेम्पलेट सिग्नल पैरामीटर प्राप्त करने का कोई तरीका है? क्या मैंने प्रस्तावित एक बेहतर वास्तुकला है?

+0

मुझे लगता है कि यदि आप बूस्ट के इस std :: वेक्टर के उपयोग के छद्म कोड देते हैं तो यह अधिक समझदार हो सकता है। मात्रा क्या इसे रन-टाइम पॉलीमोर्फिज्म चाहिए? – user204724

+0

मुझे नहीं लगता कि आपके पास पहले से मौजूद दो से बेहतर समाधान है। क्या आपने बूस्ट सिग्नल या सिग्नल 2 का उपयोग करने पर विचार किया है जहां टेम्पलेट पैरामीटर का उपयोग किया जा सकता है? – baysmith

उत्तर

1

वहाँ QVariant प्रकार है - आप
उस पर अपने कस्टम उप-प्रकार बना सकते हैं और पैरामीटर के रूप में उपयोग कर सकते हैं (अगर मैं अपने सही समझते हैं और कि तुम क्या चाहते हो) संकेतों में
http://doc.trolltech.com/qq/qq14-metatypes.html#customtypesinqvariant

+0

दुर्भाग्यवश, मुझे यह पूरा समाधान नहीं लगता है। प्रश्न में मेरा संपादन देखें। –

1

एक सरलीकरण आपके दो-स्तरित दृष्टिकोण के लिए कक्षा टेम्पलेट के लिए 0 -कक्षा गैर-टेम्पलेट आधार के रूप में होगीजैसे

class DataSourceBase : public QObject { 
    Q_OBJECT 
    ... 
    signals: 
     void samplesAcquired(TimeStamp ts, unsigned long nsamples); 
}; 

template<T,U> //sample type and units 
class DataSource : public DataSourceBase { 
    public: 
     typedef std::vector<boost::units::quantity<U,T> > SampleVector 
     virtual shared_ptr<SampleVector> acquiredData(TimeStamp ts, unsigned long nsamples); 
}; 

नोट कुछ इस दृष्टिकोण को दोष क्यूटी के मेटा-वस्तु प्रणाली में इसके बारे में कोई जानकारी नहीं है जब से तुम वर्ग टेम्पलेट में Q_OBJECT मैक्रो का उपयोग नहीं कर सकते हैं कि।

1

क्यूटी क्लास टेम्पलेट्स को पसंद नहीं करता जो QObject से प्राप्त होता है। यदि आपको QObject के रनटाइम आत्मनिरीक्षण की आवश्यकता नहीं है, तो आप इसके बजाय Boost.Signals का उपयोग करना चाहेंगे, जिसमें यह समस्या नहीं है।

एक क्यूटी परियोजना में बूस्ट सिग्नल लाइब्रेरी का परिचय देना थोड़ा चुनौतीपूर्ण हो सकता है। Boost.Signals में, signals एक नामस्थान है जबकि Qt #define s signal से protected पर है। आपको यह सुनिश्चित करना चाहिए कि बूस्ट सिग्नल को पेश करने से पहले, आपके क्यूटी प्रोजेक्ट को QT_NO_KEYWORDS परिभाषित किया गया है (CONFIG += no_keywords qmake में)।

0

आप वास्तव में अपने कोड में छोटे बदलाव के साथ टेम्पलेट्स के साथ क्यूटी कक्षाओं का उपयोग कर सकते हैं।

क्यूटी कक्षाओं और टेम्पलेट्स के साथ समस्या यह है कि मेटा ऑब्जेक्ट जानकारी उत्पन्न करने वाला मॉक टूल है, इसे टेम्पलेट्स पर कोई जानकारी नहीं है, लेकिन जेनरेट कोड को मॉक से आने की आवश्यकता नहीं है।

आप Verdigris का उपयोग अपने सी ++/QObject वर्ग बनाने के लिए कर सकते हैं कि होगा बिना किसी समस्या के टेम्पलेट्स, इस तरह के कोड के लिए MOC कदम को दरकिनार साथ काम करते हैं।

संबंधित मुद्दे