QPointer for accessing object methods

855 Views Asked by At

have a strange problem using QPointer for accessing object method from a different, not related, object.

I've prepared a little example to explain it better.

I created two QWidget, Widget_A and Widget_B in a simple QDialog.

I need to access from Widget_B a public method of Widget_A: I passed widget_a pointer to a method of widget_b for QPointer assignment. Widget_A contains a QLineEdit that I want to clear from Widget_B.

The problem is when hitting pushButton_B nothing happens to lineEdit_A. Console doesn't show any problem, so the most obvious reason is Widget_B is working on a different Widget_A object, not the one I passed.

I also created a connection from QWidget_A to QWidget_B so when editing lineEdit_A a label_B text is changed accordingly: this works.

Before asking, I need a QPointer since in my real project Widget_A could be deleted. Can you explain where I'm wrong? Should I choose a different way? Thanks. Follow some snippets

widget_a.h

class Widget_A : public QWidget
{
    Q_OBJECT

public:
    explicit Widget_A(QWidget *parent = 0);
    ~Widget_A();

    void clearLineEdit_A();

signals:
    void lineEdit_A_changed(const QString &);

private slots:
    void on_lineEdit_A_textChanged(const QString &arg1);

private:
    Ui::Widget_A *ui;
};

widget_a.cpp

Widget_A::Widget_A(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget_A)
{
    ui->setupUi(this);
    ui->lineEdit_A->setText("write something here...");
    ui->lineEdit_A->selectAll();
}

Widget_A::~Widget_A()
{
    delete ui;
}

void Widget_A::clearLineEdit_A()
{
    ui->lineEdit_A->clear();
}

void Widget_A::on_lineEdit_A_textChanged(const QString &arg1)
{
    emit lineEdit_A_changed(arg1);
}

widget_b.h

class Widget_B : public QWidget
{
    Q_OBJECT

public:
    explicit Widget_B(QWidget *parent = 0);
    ~Widget_B();

    void controlWidget(QWidget *w);

private slots:
    void changeLabel_B(const QString &text);

    void on_pushButton_B_clicked();

private:
    Ui::Widget_B *ui;
    QPointer<QWidget> qPtrWdgt;
};

widget_b.cpp

Widget_B::Widget_B(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget_B)
{
    ui->setupUi(this);
}

Widget_B::~Widget_B()
{
    delete ui;
}

void Widget_B::controlWidget(QWidget *w)
{
    qPtrWdgt = w;
    connect(qPtrWdgt, SIGNAL(lineEdit_A_changed(const QString &)),
                  this, SLOT(changeLabel_B(const QString &)));
}

void Widget_B::changeLabel_B(const QString &text)
{
    ui->label_B->setText(text);
}

void Widget_B::on_pushButton_B_clicked()
{
    Widget_A(qPtrWdgt).clearLineEdit_A();
}

dialog.h

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;

    Widget_A *widget_a;
    Widget_B *widget_b;
};

dialog.cpp

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    widget_a = new Widget_A(this);
    widget_b = new Widget_B(this);
    widget_b->controlWidget(widget_a);

    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(widget_a);
    mainLayout->addWidget(widget_b);
    setLayout(mainLayout);
}
1

There are 1 best solutions below

1
On
Widget_A(qPtrWdgt).clearLineEdit_A();

This creates a new Widget_A by using the Widget_A(QWidget *) constructor, then calls clearLineEdit_A() on it.

If you define qPtrWdgt as QPointer<Widget_A> instead, and since QPointer overloads operator->, then you can use:

qPtrWdgt->clearLineEdit_A();

You'll need to include Widget_A's header in Widget_B's header too.