2010-04-06 18 views
7

मैंने विजेट पेरेंट के स्लॉट तक पहुंचने के परीक्षण के लिए एक छोटा प्रोग्राम लिखा था।क्यूटी - कॉलिंग विजेट माता-पिता के स्लॉट

विजेट::

namespace Ui 
{ 
    class Widget; 
} 

class Widget : public QWidget 
{ 
    Q_OBJECT 

public: 
    Widget(QWidget *parent = 0); 
    ~Widget(); 
    QLabel *newlabel; 
    QString foo; 

public slots: 
    void changeLabel(); 

private: 
    Ui::Widget *ui; 
}; 

Widget::Widget(QWidget *parent) 
    : QWidget(parent), ui(new Ui::Widget) 
{ 
    ui->setupUi(this); 
    customWidget *cwidget = new customWidget(); 
    newlabel = new QLabel("text"); 
    foo = "hello world"; 
    this->ui->formLayout->addWidget(newlabel); 
    this->ui->formLayout->addWidget(cwidget); 

    connect(this->ui->pushButton,SIGNAL(clicked()),cwidget,SLOT(callParentSlot())); 
    connect(this->ui->pb,SIGNAL(clicked()),this,SLOT(changeLabel())); 
} 

void Widget::changeLabel(){ 
    newlabel->setText(this->foo); 
} 

और customWidget: मूल रूप से, यह दो वर्गों है

class customWidget : public QWidget 
{ 
    Q_OBJECT 
public: 
    customWidget(); 
    QPushButton *customPB; 

public slots: 
    void callParentSlot(); 
}; 

customWidget::customWidget() 
{ 
    customPB = new QPushButton("customPB"); 
    QHBoxLayout *hboxl = new QHBoxLayout(); 
    hboxl->addWidget(customPB); 
    this->setLayout(hboxl); 
    connect(this->customPB,SIGNAL(clicked()),this,SLOT(callParentSlot())); 
} 

void customWidget::callParentSlot(){ 
    ((Widget*)this->parentWidget())->changeLabel(); 
} 
मुख्य कार्य में

, मैं बस उस पर) विजेट का एक उदाहरण है, और कहा जाता है शो (बनाया । इस विजेट इंस्टेंस में एक लेबल, क्यूस्ट्रिंग, कस्टमविड्ज क्लास का एक उदाहरण है, और दो बटन (यूई क्लास, पुशबटन और पीबी के अंदर) हैं। बटनों में से एक अपनी स्लॉट को चेंज लेबल() नामक स्लॉट कहता है, जैसा कि नाम से पता चलता है, उसमें मौजूद क्यूस्ट्रिंग में जो भी सेट है, उस लेबल को बदलता है। मैंने बस उस परिवर्तन को जांचने के लिए बनाया है लेबल() ने काम किया। यह बटन ठीक काम कर रहा है। दूसरा बटन कस्टमविड्ज इंस्टेंस में स्लॉट को कॉल करता है, जिसे कॉलपैंटस्लॉट() नाम दिया जाता है, जो बदले में चेंज लेबल() स्लॉट को अपने माता-पिता में कॉल करने का प्रयास करता है। चूंकि इस मामले में मुझे पता है कि इसके माता-पिता वास्तव में विजेट का एक उदाहरण है, मैंने parentWidget() को विजेट * पर वापसी मूल्य डाला। यह बटन प्रोग्राम को दुर्घटनाग्रस्त करता है। मैंने कस्टमविड्ज के भीतर कस्टम बटन को भी कॉल करने का प्रयास करने के लिए कस्टमविड्ज के भीतर एक बटन बनाया है, लेकिन यह प्रोग्राम को भी क्रैश करता है। मैंने this प्रश्न पर क्या किया था। मैं क्या खो रहा हूँ?

+0

आप माता-पिता के स्लॉट को कॉल करने का प्रयास क्यों कर रहे हैं? चूंकि यह पहले से ही एक स्लॉट है, आप बच्चे से संकेत क्यों नहीं छोड़ते हैं और इस सिग्नल को माता-पिता के स्लॉट से जोड़ते हैं? – erelender

+0

ऐसा इसलिए है क्योंकि जब भी मैं बच्चे विजेट में कुछ बदलाव करता हूं तो मैं पैरेंट विजेट में कुछ चर अपडेट करना चाहता हूं। बच्चे को अपने माता-पिता विजेट के स्लॉट को कॉल करने के अलावा मैं किसी अन्य तरीके से नहीं समझ पाया। –

+0

समस्या यह है कि बाल विजेट में परिवर्तन जो मैं चिंतित हूं, बच्चे विजेट में बटन द्वारा ट्रिगर किया गया है, इसलिए मुझे बच्चे विजेट के भीतर से मूल विजेट पर मौजूद चर को अपडेट करने का एक तरीका पता लगाने की आवश्यकता है। –

उत्तर

2

आपने कभी भी अपने customWidget उदाहरण के लिए पैरेंट विजेट सेट नहीं किया है। तो, this->parentWidget() एक पूर्ण सूचक लौटने की संभावना है। निम्नलिखित परिवर्तन करें:

customWidget *cwidget = new customWidget(this); 
... 
customWidget(QWidget *parent); 
... 
customWidget::customWidget(QWidget *parent) : QWidget(parent) 

मैं गतिशील_कास्ट का उपयोग करने और वापसी मूल्य की जांच करने की सलाह भी दूंगा। यह उन दोनों मामलों में आपके दुर्घटना को रोकता है जहां माता-पिता नल हैं और जहां माता-पिता सही वर्ग का नहीं है।

void customWidget::callParentSlot() 
{ 
    Widget *w = dynamic_cast<Widget *> (this->parentWidget()); 
    if (0 != w) 
     w->changeLabel(); 
    /* else handle the error */ 
} 

एक और दृष्टिकोण सिग्नल और स्लॉट इंटरफ़ेस के माध्यम से अभिभावक स्लॉट को कॉल करना होगा। विजेट कन्स्ट्रक्टर में विजेट स्लॉट पर नया कस्टमविड्ज सिग्नल कनेक्ट करें। फिर आप निम्नानुसार कस्टम विजिट से स्लॉट को कॉल कर सकते हैं।

emit callParentSignal(); 
+0

यह अभी भी अपने माता-पिता को स्पष्ट रूप से सेट करने के बाद भी दुर्घटनाग्रस्त हो जाता है। Addwidget (cwidget) कहलाते समय cwidget के माता-पिता को स्वचालित रूप से सेट नहीं किया जाना चाहिए? –

+0

मुझे पता है कि यह एक अच्छा विचार नहीं है, लेकिन मैं ऐसा करने के साथ फंस गया हूं या एक ऐप से कोड का एक बड़ा हिस्सा फिर से लिखना चाहता हूं, मैं –

+0

के साथ काम कर रहा हूं, मुझे यकीन नहीं है कि addWidget इसे पुन: दर्ज करता है या नहीं। फिर भी, क्या आप वाकई माता-पिता के रूप में सही विजेट का उपयोग करते हैं? –

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