2011-03-01 13 views
61

मैं QActions और QMenus के एक समूह के साथ mouseReleaseEvent ओवरराइड करना चाहते करने के लिए एक तर्क पासिंग ...एक स्लॉट

connect(action1, SIGNAL(triggered()), this, SLOT(onStepIncreased())); 

connect(action5, SIGNAL(triggered()), this, SLOT(onStepIncreased())); 

connect(action10, SIGNAL(triggered()), this, SLOT(onStepIncreased())); 

connect(action25, SIGNAL(triggered()), this, SLOT(onStepIncreased())); 

connect(action50, SIGNAL(triggered()), this, SLOT(onStepIncreased())); 

तो मैं स्लॉट onStepIncreased लिए एक तर्क है (जैसा कि आप कल्पना कर सकते वे कर रहे हैं 1 पास करना चाहते हैं , 5,10,25,50)। क्या आप जानते हैं कि मैं इसे कैसे कर सकता हूं?

+1

पैरामीटर पास करने के बजाय, सिग्नल के अंदर प्रेषक() का विश्लेषण करने पर विचार करें। –

उत्तर

104

QSignalMapper का उपयोग करें। इस तरह:

QSignalMapper* signalMapper = new QSignalMapper (this) ; 
connect (action1, SIGNAL(triggered()), signalMapper, SLOT(map())) ; 
connect (action5, SIGNAL(triggered()), signalMapper, SLOT(map())) ; 
connect (action10, SIGNAL(triggered()), signalMapper, SLOT(map())) ; 
connect (action25, SIGNAL(triggered()), signalMapper, SLOT(map())) ; 
connect (action50, SIGNAL(triggered()), signalMapper, SLOT(map())) ; 

signalMapper -> setMapping (action1, 1) ; 
signalMapper -> setMapping (action5, 5) ; 
signalMapper -> setMapping (action10, 10) ; 
signalMapper -> setMapping (action25, 25) ; 
signalMapper -> setMapping (action50, 50) ; 

connect (signalMapper, SIGNAL(mapped(int)), this, SLOT(onStepIncreased(int))) ; 
+0

मुझे अभी भी समय याद है, जब क्यूटी के पास QSignalMapper नहीं था, और एकमात्र समाधान उसी स्लॉट से जुड़े ऑब्जेक्ट्स पर संपत्ति सेट कर रहा था और प्रेषक() -> संपत्ति (...) –

+0

@ किमिल क्लाइमेक का उपयोग करने की आवश्यकता नहीं थी ; आप अपना खुद का मैपर लिख सकते थे :) –

+0

यदि मेरा 'संदर्भ' पैरामीटर उस वर्ग को लक्षित करता है जिसका क्रियाओं को कोई एसेस नहीं है? तो फिर भी, 'संदर्भ' सिग्नलैपर को क्रियाओं तक पहुंच नहीं होगी, या यदि मेरे पास एक ही कक्षा में साइनमैपपर होगा, तो यह पहचानने वाले स्लॉट के लिए गलत संदर्भ होगा। – dhein

9

QObject::sender() फ़ंक्शन उस ऑब्जेक्ट को पॉइंटर देता है जिसने स्लॉट पर संकेत दिया है। आप यह जानने के लिए इसका उपयोग कर सकते हैं कि कौन सी कार्रवाई ट्रिगर की गई थी

+0

लेकिन कार्रवाई ऑब्जेक्ट्स स्लॉट से पहुंच योग्य नहीं हैं .. –

+1

मैं क्षमा चाहता हूं? स्लॉट QObject के उप-वर्ग का सदस्य है, इस प्रकार यह एक QObject :: प्रेषक() सदस्य भी है। बस प्रेषक() को कॉल करें, और आपको एक क्यूओब्जेक्ट * दिया जाएगा जो आपकी कार्रवाई को इंगित करता है। उसके बाद आप अधिक जानकारी एकत्र करने के लिए एक अधिग्रहित कार्रवाई के objectName() या property() का उपयोग कर सकते हैं। यदि आप वास्तव में चाहते हैं तो आप इसे एक एक्शन ऑब्जेक्ट में भी परिवर्तित कर सकते हैं, लेकिन मैं इसकी अनुशंसा नहीं करता। – Septagram

1

हो सकता है कि आप एक m_increase सदस्य चर के साथ QAction को उपclass कर सकें।
ट्रिगर() सिग्नल को अपने नए क्यूएक्शन सबक्लास पर स्लॉट से कनेक्ट करें और सही पैरामीटर के साथ एक नया सिग्नल (उदा। ट्रिगर (इंट नंबर) उत्सर्जित करें।
उदा।

class MyAction:public QAction 
{ 
public: 
    MyAction(int increase, ...) 
     :QAction(...), m_increase(increase) 
    { 
     connect(this, SIGNAL(triggered()), this, SLOT(onTriggered())); 
    } 
protected Q_SLOTS: 
    void onTriggered() 
    { 
     emit triggered(m_increase); 
    } 

Q_SIGNALS: 
    void triggered(int increase); 

private: 
    int m_increase; 
}; 
79
क्यूटी 5 के साथ

और एक सी ++ 11 संकलक, इस तरह के काम करने के लिए मुहावरेदार रास्ता connect को एक functor दे रहा है:

connect(action1, &QAction::triggered, this, [this]{ onStepIncreased(1); }); 
connect(action5, &QAction::triggered, this, [this]{ onStepIncreased(5); }); 
connect(action10, &QAction::triggered, this, [this]{ onStepIncreased(10); }); 
connect(action25, &QAction::triggered, this, [this]{ onStepIncreased(25); }); 
connect(action50, &QAction::triggered, this, [this]{ onStepIncreased(50); }); 

connect को तीसरा तर्क नाममात्र वैकल्पिक है। इसका उपयोग धागा संदर्भ स्थापित करने के लिए किया जाता है जिसमें मज़ेदार निष्पादित करेगा। यह हमेशा आवश्यक होता है जब मज़ेदार QObject उदाहरण का उपयोग करता है। यदि मज़ेदार एकाधिक QObject उदाहरणों का उपयोग करता है, तो उनके पास कुछ सामान्य माता-पिता होना चाहिए जो उनके जीवनकाल का प्रबंधन करते हैं और मज़ेदार को उस माता-पिता को संदर्भित करना चाहिए, या यह सुनिश्चित किया जाना चाहिए कि वस्तुएं मज़ेदार से निकल जाएंगी।

विंडोज पर, यह MSVC2012 & नए में काम करता है।

+5

सी ++ 11 लैम्बडास और क्यूटी 5 की एक संयोजन को एक सिग्नल से कनेक्ट करने की क्षमता इतनी उपयोगी और अभी तक निहित सुविधा है। – Carlton

+0

मैंने इस मामले को मेरे मामले में अनुकूलित किया। हालांकि, अगर मैं 'QAction :: ट्रिगर' के बजाय 'सिग्नल (ट्रिगर (बूल))' का उपयोग करता हूं तो यह एक त्रुटि फेंकता है। क्या कोई मुझे बता सकता है क्यों? – Deniz

+0

यह एक त्रुटि "फेंक" नहीं करता है। कंपाइलर शिकायत करता है, और त्रुटि संदेश आपको बताएगा क्यों: कोई 'QObject :: कनेक्ट' अधिभार नहीं है जो दूसरे तर्क के रूप में' कॉन्स्ट char * 'लेता है और तीसरा या चौथा तर्क के रूप में एक मज़ेदार होता है। क्यूटी 4-शैली 'कनेक्ट' सिंटैक्स नए वाक्यविन्यास के साथ मिश्रण नहीं करता है। यदि आप पुराने वाक्यविन्यास का उपयोग करना चाहते हैं, तो आप मज़दूरों से जुड़ने की आसानी को जब्त करते हैं (भले ही आपके पास सी ++ 11 कंपाइलर था लेकिन क्यूटी 4 का उपयोग किया गया हो)। –

0
QVector<QAction*> W(100); 
W[1]= action1; 
W[5]= action5; 
W[10]= action10; 
W[25]= action25; 
W[50]= action50; 

for (int i=0; i<100; ++i) 
{ 
    QSignalMapper* signalmapper = new QSignalMapper(); 
    connect (W[i], SIGNAL(triggered()), signalmapper, SLOT(map())) ; 
    signalmapper ->setMapping (W[i], i); 
    connect (signalmapper , SIGNAL(mapped(int)), this, SLOT(onStepIncreased(int))); 
} 
संबंधित मुद्दे