2010-04-06 10 views
7

Escribí un pequeño programa para probar el acceso al widget de un padre. Básicamente, tiene dos clases:Qt - Ranuras para padres del widget de llamadas

Widget:

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); 
} 

y 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(); 
} 

en la función principal, simplemente crea una instancia de control, y se llama show() en él . Esta instancia de widget tiene una etiqueta, un QString, una instancia de la clase customWidget y dos botones (dentro de la clase ui, pushButton y pb). Uno de los botones llama a un espacio en su propia clase llamado changeLabel(), que, como su nombre indica, cambia la etiqueta a lo que esté establecido en el QString que contiene. Lo hice solo para comprobar que changeLabel() funcionó. Este botón funciona bien. El otro botón llama a una ranura en la instancia del widget personalizado, llamada callParentSlot(), que a su vez intenta llamar al espacio changeLabel() en su matriz. Como en este caso sé que su padre es de hecho una instancia de Widget, eché el valor de retorno de parentWidget() a Widget *. Este botón bloquea el programa. Hice un botón dentro de customWidget para tratar de llamar al slot principal de Widget personalizado, pero también bloquea el programa. Seguí lo que estaba en la pregunta this. ¿Qué me estoy perdiendo?

+0

¿Por qué estás tratando de llamar a la ranura de los padres? Como ya es una ranura, ¿por qué no emite una señal del niño y conecta esta señal a la ranura de los padres? – erelender

+0

Es porque quiero actualizar algunas variables en el widget principal cada vez que realizo algunos cambios en el widget hijo. No pude encontrar otra forma que no sea hacer que el niño llame al espacio del widget de sus padres. –

+0

El problema es que los cambios en el widget hijo que me preocupan son activados por los botones en el widget hijo, así que necesito encontrar una manera de actualizar las variables que están en el widget padre desde el widget hijo. –

Respuesta

2

Nunca configuró el widget principal para su instancia customWidget. Por lo tanto, es probable que this->parentWidget() devuelva un puntero NULL. Realice los siguientes cambios:

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

También recomendaría usar un dynamic_cast y verificar el valor de retorno. Esto fue para evitar que se bloquee tanto en el caso en que el padre es NULL como el padre no es de la clase correcta.

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

Otro enfoque sería llamar a la ranura principal a través de la interfaz de señales y ranuras. Conecte la nueva señal de widget personalizada a la ranura de widgets en el constructor de widgets. Luego puede llamar al slot desde customWidget de la siguiente manera.

emit callParentSignal(); 
+0

Todavía se bloquea, incluso después de establecer explícitamente su elemento primario. ¿El padre de cwidget no debería establecerse automáticamente cuando se llama a addWidget (cwidget)? –

+0

Sé que no es una buena idea, pero tengo que hacer esto o tener que volver a escribir una gran parte del código de una aplicación con la que estoy trabajando –

+0

No estoy seguro de si addWidget lo reparige. Aun así, ¿estás seguro de que usa el widget correcto como padre? –

Cuestiones relacionadas