I am concerned about making possible a library of widgets developed under Qt 5.9 to be upgraded in the future without having to recompile the code that already uses it. Of course I've started with the PImpl idiom and the Qt version of it described here and here.
However while trying to adapt my code, I came up with the idea, that instead of adding new data members and moving them to a separate private class, I could use the Qt's signal/slot mechanism with lambda functions and have only local variables. Let's illustrate the idea with the following example:
Variant A:
class Foo : public QWidget
{
Q_OBJECT
public:
explicit Foo(QWidget *parent = nullptr);
private:
// A bunch of data members
QPushButton *m_button;
QLineEdit *m_lineEdit;
QCheckBox *m_checkBox;
QString m_str;
private slots:
void on_pushButtonClicked();
void on_checkBoxStateChanged(int state);
}
Foo::Foo(QWidget *parent) :
QWidget(parent),
m_button(new QPushButton("Click me", this));
m_lineEdit(new QLineEdit(this)),
m_checkBox(new QCheckBox(this)),
m_str("Initial text")
{
connect(button, &QPushButton::clicked, this, &Foo::on_pushButtonClicked);
connect(checkBox, &QCheckBox::stateChanged, this, &Foo::on_checkBoxStateChanged);
}
Foo::on_pushButtonClicked()
{
m_str = m_lineEdit->text();
m_lineEdit->setDisabled(m_checkBox->isChecked());
}
Foo::on_checkBoxStateChanged(int state)
{
m_button->setText(state == Qt::Checked ? m_str : "Click me")
}
Variant B:
class Foo : public QWidget
{
Q_OBJECT
public:
explicit Foo(QWidget *parent = nullptr);
}
Foo::Foo(QWidget *parent) : QWidget(parent)
{
QPushButton *button = new QPushButton("Click me", this);
QLineEdit *lineEdit = new QLineEdit(this);
QCheckBox *checkBox = new QCheckBox(this);
QString str("Initial text");
connect(button, &QPushButton::clicked, [=](){
str = lineEdit->text();
lineEdit->setDisabled(checkBox->isChecked());
});
connect(checkBox, &QCheckBox::stateChanged, [=](int state){
button->setText(state == Qt::Checked ? str : "Click me")
});
}
So, for Variant B - apart from being more compact, it does not contain any class data members, so there are no variables to hide, hence no need for a D-pointer. The binary compatibility is still guaranteed though (or is it?), if in the future the constructor is reimplemented with additional local variables used in the same signal/slot manner. Am I right to think this will work or such an approach won't do the trick at all?
Note: For more info about using lambdas as slots in Qt check the comment by @Igor Tandetnik here.
Aucun commentaire:
Enregistrer un commentaire