使用QPointer
从不同的、不相关的对象访问对象方法时遇到了一个奇怪的问题。
我准备了一个小例子来更好地解释它。
我在一个简单的QDialog
中创建了两个QWidget
,Widget_A和Widget_B。
我需要从Widget_B访问Widget_a的一个公共方法:我为QPointer
赋值传递了一个指向Widget_B方法的Widget_a指针。Widget_A包含一个QLineEdit
,我想从Widget_B中清除它。
问题是,当按下按钮_B时,lineEdit_A不会发生任何变化。控制台没有显示任何问题,所以最明显的原因是Widget_B正在处理不同的Widget_a对象,而不是我传递的那个对象。
我还创建了一个从QWidget_a到QWidget_B的连接,所以当编辑lineEdit_a时,label_B文本会相应地更改:这很有效。
在询问之前,我需要一个QPointer
,因为在我的真实项目中,Widget_a可能会被删除。你能解释一下我错在哪里吗?我应该选择不同的方式吗?谢谢跟随一些片段
小工具_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);
}
小工具_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();
}
对话框.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;
};
对话框.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);
}
Widget_A(qPtrWdgt).clearLineEdit_A();
这将使用Widget_A(QWidget *)
构造函数创建一个新的Widget_A
,然后在其上调用clearLineEdit_A()
如果将qPtrWdgt
定义为QPointer<Widget_A>
,并且由于QPointer
重载operator->
,则可以使用:
qPtrWdgt->clearLineEdit_A();
您还需要在Widget_B
的标头中包含Widget_A
的标头。