2

我在 QT 和 QML 中定义了一个基于 QAbstractListModel 的类,我将此模型设置为 GridView。它工作完美。如果我更改模型中的数据,我会调用重置函数,GridView 会显示更新的数据。但有时我会更改完整的模型数据(即不仅数据更改,而且其计数也更改)。在这种情况下,当我重置数据时,GridView 不会显示更新的模型。我还尝试为我的模型创建一个新对象并更改了 GridView 模型,但仍然没有效果。

这是基本的代码片段。

// DataEngine.h
class DataEngine : public QAbstractListModel
{
    Q_OBJECT
public:
    .....
public: // Overrides
    int rowCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
}
// main.c
DataEngine *data = new DataEngine();
view.rootContext()->setContextProperty("DataModel", data)

// QML File
GridView {
.....
id: view
model: DataModel
.....
}

// After completely changing data (i.e earlier it has 256 rows, now it has say 0 row)
// I tried
view.rootContext()->setContextProperty("NewDataModel", data)
// QML Code
view.model = NewDataModel     // No effect.

在我看来,数据正在发生变化,但 GridView 并未使用新数据进行更新。

任何帮助表示赞赏。

最好的问候, Farrukh Arshad

4

2 回答 2

3

我怀疑您没有通知底层基础模型您的数据已更改。请参阅QAbstractItemModel 的这一部分,了解有关您需要在子类中执行的操作的详细信息。特别是,下面这句话说了很多:

在实现这些功能时,重要的是要通知任何连接的视图在模型尺寸发生之前和之后发生的变化:

如果要删除减少数据,则必须提供 removeRows 的实现,如果要增加数据,则必须提供 insertRows 的实现。就我而言,因为我有来自自己来源的数据,所以我只是删除了该数据并将 rowIndex 返回为 0 无效。我刚刚添加了一个空的 removeRows 实现,其中 beginRemoveRows 和 endRemoveRows 在 return true 内,并发出了这个信号。有了这个信号,我的视图知道数据计数发生了变化,所以它调用了 rowCount 函数,我返回了 0。

于 2012-09-04T12:15:57.637 回答
1

问题已解决。Wes Hardaker 提供的指针是完美的,我已经通过编辑他的答案提到了细节。这是我分享的代码。您的模型子类必须提供 removeRows / insertRows 的实现。使用这些函数,视图知道当您调用 beginRemoveRows / endRemoveRows 和 beginInsertRows / endInsertRows 时数据计数已更改,并且视图将调用您的 rowCount 函数,您可以在其中提供更新的计数。扩展问题中提到的代码。

// When changing the data, following two lines are being called on a 
// button press from the QML.
// Invokable method

delete this->data;         // As mentioned in question data is DataEngine object.
this->data = NULL;

// DataEngine destructor
DataEngine::~DataEngine()
{
    // Remove all rows from the data model so that
    // the model view knows the data is changed
    removeAllRows();
}
void DataEngine::removeAllRows()
{
    removeRows(0, this->getBufferSize(), this->index(0,0));
}
bool DataEngine::removeRows(int row, int count, const QModelIndex &parent)
{
    beginRemoveRows(QModelIndex(), row, row + count - 1);
    // You can delete your actual data here as well, I was deleting it in the 
    // destructor of DataEngine.
    endRemoveRows();
    return true;
}
于 2012-09-04T19:17:55.767 回答