简体   繁体   中英

Using QSharedPointer as Data Model

I have an application with multiple "input widgets" written as inpependent classes, that all store a shared pointer of the respective class that's data thay show. In each of these widgets a user can see and manipulate some different data. All of these data serves as input and also as output of a calculation. Two of these widgets share the same data/class, but manipulate different members of this class.

How can I achieve that manipulating the data in one widget automaticly updates the other widget?

So the question is: Can I share a QSharedPointer between two classes, then connect it to a "this"-slot so that when I manipulate the pointer's value in one of these classes, the other one can do something with this data(as updating it's gui)?

My intention was, since I had to store the actual data in another QSharedPointer, to make a connect on that shared pointer that tells the other widget.

I thought of something like this:


#include <QWidget>
#include <QSpinBox>

class MyWidget : QWidget // A template widget to be placed in MainWindow
{
    Q_OBJECT
public:
    MyWidget()
    {
        this->spinBox = new QSpinBox(this);
        connect(this->spinBox, &QSpinBox::editingFinished, this, &MyWidget::evokedByGuiManipulation);
        connect(this->data.data(), &foo::changed, this, &MyWidget::updateGui);
    }
    virtual ~MyWidget() {delete spinBox;}

public slots:
    void setData(QSharedPointer<foo> value)
    {
        data = value;
    }

    void evokedByGuiManipulation()
    {
        data->manipulate(spinBox->value());
    }

    void updateGui()
    {
        this->spinBox->setValue(data->getData()->datamember);
    }
protected:
    QSharedPointer<foo> data;

private:
    QSpinBox *spinBox;
};

UPDATE

And class foo is actually a wrapper that stores the actual data class baz . Like:

class foo
{
    Q_GADGET
public:
    foo(){}
    QSharedPointer<baz> getData() {return actualData;}

public slots :
    void setActualData(QSharedPointer<baz> value)
    {
        actualData = value;
        emit changed();
    }

signals:
    void changed();

private:
    QSharedPointer<baz> actualData;
};

You can do this, assuming that foo::manipulate emits a signal that your other widget connects to.

I would also advise ensuring that foo::operator= emit changed , so that setData updates both widgets.

Not strictly related to your question, there are errors in the code you have shown.

connect(this->spinBox, &QSpinBox::editingFinished, this, &MyWidget::evokedByGuiManipulation);

editingFinished doesn't have a QSharedPointer<baz> to pass to evokedByGuiManipulation . Did you mean

data->manipulate(spinBox->value());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM