2011-04-19 8 views
7

में एक गतिशील स्लॉट बनाना मैं स्लॉट गतिशील रूप से बनाने और उन्हें कनेक्ट करने की कोशिश कर रहा हूं। मैं गतिशील रूप से pushButtons बनाने और मौजूदा स्लॉट के साथ कनेक्ट करने में सक्षम हूं। लेकिन अगर मेरे पास कुछ सदस्य कार्यों के साथ कक्षा है और मैं इन कार्यों को स्लॉट के रूप में उपयोग करना चाहता हूं तो क्या होगा।क्यूटी

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

-CV

उत्तर

9

यह बहुत समझ में आता है। मुझे लगता है कि QSignalMapper वह नहीं है जो आप चाहते हैं। अपने कार्यों तर्क नहीं है, तो, हो सकता है कुछ इस तरह पर्याप्त है:

class SlotForwarder : public QObject 
{ 
    Q_OBJECT 

public: 

    typedef void (*Function)(); // or whatever. I never get this syntax right... 

    SlotForwarder(Function function, QObject* parent = 0) 
     : QObject(parent) 
     , m_fptr(function) 
    {} 

public slots: 

    void forward() 
    { 
     m_fptr(); 
    } 

private: 

    Function m_fptr; 
}; 

प्रत्येक कार्य आप संपुटित और हमेशा की तरह forward से कनेक्ट करना चाहते के लिए एक बनाएं।


अब, अगर वे तर्क है, हो सकता है इस क्यूटी त्रैमासिक लेख सहायता के हो सकता है।

Dynamic Signals and Slots by Eskil A. Blomfeldt

तकनीक qt_metacall विधि अपने आप को reimplementing शामिल है।

int QObject::qt_metacall(QMetaObject::Call call, int id, void **arguments) 

कॉल metacall की तरह है: स्लॉट, संकेत, पढ़ने या लिखने संपत्ति, आदि हर स्लॉट एक आईडी है विधि इस हस्ताक्षर हैं। तर्क सरणी के अंदर पैरामीटर पैक किए गए हैं (मान या पॉइंटर्स द्वारा)। कोड उत्पन्न करने वाले कोड को पढ़ना एक अच्छा तरीका है यह समझने का एक अच्छा तरीका है कि यह सब कैसे काम करता है।

कच्चे फ़ंक्शन हस्ताक्षर के बारे में डेटा केवल संकलन समय के दौरान उपलब्ध है, लेकिन रनटाइम पर स्लॉट का समाधान किया जाता है। उस विसंगति के कारण, आपको फ़ंक्शंस को टेम्पलेट एडेप्टर प्रकार में लपेटने की आवश्यकता होगी जो qt_metacall के कार्यान्वयन के लिए निरंतर इंटरफ़ेस प्रस्तुत करता है और arguments सरणी को फ़ंक्शन समझा सकता है (सीएफ। पायथन unpack ऑपरेटर) में परिवर्तित करता है। Boost.Signals उस तरह का template hackery करता है।

+0

धन्यवाद एक स्लॉट के रूप में किसी भी सदस्य समारोह का उपयोग करने के। यह सामान्य कार्यों के लिए काम करना चाहिए, लेकिन सदस्य कार्यों के लिए नहीं। क्या आप कक्षा सदस्य कार्यों के लिए ऐसा करने के तरीके के बारे में जानते हैं? – blueskin

+0

धन्यवाद एंड्रफ़। मुझे पता चला कि सदस्य tr1 :: बाइंड का उपयोग कर भाग लेता है। मैंने नीचे अपना कोड पोस्ट कर दिया है। एक बार मेरे पास गतिशील UI निर्माण (सहित गतिशील सिग्नल/स्लॉट कनेक्शन) के लिए एक छोटा ऐप है, तो मैं एक लिंक पोस्ट करूंगा। – blueskin

2

andref के कोड का एक निरंतरता इतनी के रूप में कोड के लिए

class SlotForwarder : public QObject 
    { 
     Q_OBJECT 

    public: 

     typedef void (*Function)(); 

     SlotForwarder(Function function, QObject* parent = 0) 
      : QObject(parent) 
      , m_fptr(function) 
     {} 

    public slots: 

     void forward() 
     { 
      m_fptr(); 
     } 

    private: 

     Function m_fptr; 
    }; 

    int main(){ 
     QApplication a(argc, argv); 
     MyClass myClassObject; //contains a function called MemberFunc 
     //create a slotforwarder object so 
     SlotForwarder *memberFuncSlot = new SlotForwarder (std::tr1::bind(&MyClass::MemberFunc, &myClassObject)); 
     QObject::connect(ui.button,SIGNAL(clicked()),memberFuncSlot,SLOT(forward()); 
    } 
+0

वाह! 'tr1 :: bind' बहुत अच्छा है और मैं इसके बारे में पूरी तरह से भूल गया था। – andref

+0

हाँ, मैं भी – blueskin

+0

भूल गया दिलचस्प दृष्टिकोण लेकिन आप एक सामान्य कार्यक्रम में फॉरवर्डर को कब हटाते हैं। मुझे लगता है कि एक स्मार्ट सूचक अधिक समझदार होगा – Martin