在运行时更改QML GridView模型

时间:2012-09-04 08:45:18

标签: gridview qml qabstractlistmodel

我在QT中定义了一个基于QAbstractListModel的类,在QML中我将此模型设置为GridView。它完美无缺。如果我更改模型中的数据,我会调用reset函数,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

2 个答案:

答案 0 :(得分:3)

我怀疑您未能通知基础模型您的数据已更改。有关您的子类需要执行的操作的详细信息,请参阅QAbstractItemModel的this section。特别是,下面的句子说了很多:

在实施这些功能时,务必通知任何已连接的视图,了解之前和之后模型的尺寸变化:

如果要删除减少数据,则必须提供removeRows的实现,如果要增加数据,则必须提供insertRows的实现。在我的情况下,因为我有来自我自己的数据源的数据,我只是删除了那些数据,并将rowIndex返回为0,但没有工作。我刚刚添加了一个带有beginRemoveRows&的removeRows的空实现。 endRemoveRows里面返回true,并发出此信号。使用此信号,我的视图知道数据计数已更改,因此它调用了rowCount函数,其中我返回了0.

答案 1 :(得分:1)

问题已解决。 Wes Hardaker提供的指针非常完美,我已经通过编辑他的答案提到了细节。这是我在分享代码。您的模型子类必须提供removeRows / insertRows的实现。使用这些函数,当您调用beginRemoveRows / endRemoveRows&时,视图知道数据计数已更改。 beginInsertRows / endInsertRows和view将调用你的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;
}