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);
}
This creates a new
Widget_A
by using theWidget_A(QWidget *)
constructor, then callsclearLineEdit_A()
on it.If you define
qPtrWdgt
asQPointer<Widget_A>
instead, and sinceQPointer
overloadsoperator->
, then you can use:You'll need to include
Widget_A
's header inWidget_B
's header too.