Использование QSharedPointer в качестве модели данных - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть приложение с несколькими «входными виджетами», написанными как независимые классы, которые хранят общий указатель соответствующего класса, который показывает данные, которые они показывают. В каждом из этих виджетов пользователь может видеть и манипулировать некоторыми различными данными. Все эти данные служат входными данными, а также выходными данными расчетов. Два из этих виджетов совместно используют одни и те же данные / класс, но манипулируют различными членами этого класса.

Как можно добиться, чтобы манипулирование данными в одном виджете автоматически обновляло другой виджет?

Так что вопрос : Можно ли разделить QSharedPointer между двумя классами, а затем подключить его к «this» -слоту, чтобы при манипулировании значением указателя в одном из этих классов другой мог что-то делать с этим data (как обновление, это gui)?

Мое намерение состояло в том, чтобы, поскольку мне пришлось хранить фактические данные в другом QSharedPointer, установить соединение с этим общим указателем, который сообщает другому виджету.

Я думал примерно так:


#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;
};

ОБНОВЛЕНИЕ

А класс foo на самом деле является оберткой, которая хранит фактические данные class baz. Нравится:

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;
};

1 Ответ

0 голосов
/ 21 апреля 2020

Вы можете сделать это, предполагая, что foo::manipulate испускает сигнал, к которому подключается ваш другой виджет.

Я бы также посоветовал убедиться, что foo::operator= испускает changed, чтобы setData обновлял оба виджета.

Не строго связано с вашим вопросом, в коде у вас есть ошибки

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

editingFinished не имеет QSharedPointer<baz> для перехода на evokedByGuiManipulation. Вы имели в виду

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