1

我正在学习如何将 qml 与 c++ 集成。我已经实现了一个自定义模型类StringListModel,它继承了 QAbstratListModel。而且,我有一个 main.qml 来使用StringListModel。QML 视图可以正确显示初始值。我有另一个线程要定期更改模型。我确实使用 beginResetModel() 和 endResetModel() 来指示模型已更改。

但是,尽管模型不断更改,但视图并未更新。

这是我的源代码。请教我出了什么问题。谢谢!

=== main.qml ===

Rectangle {
    width: 360
    height: 360

    Grid {
        id: gridview
        columns: 2
        spacing: 20

        Repeater {
            id: repeater
            model: StringListModel {
            id:myclass
        }

        delegate: Text {
            text: model.title
        }
    }
}

=== 自定义类.h ===

class StringListModel : public QAbstractListModel{
    Q_OBJECT

public:
    StringListModel(QObject *parent = 0);

    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;

    QHash<int, QByteArray> roleNames() const;

    void newItem();
private:
    QStringList stringList;

};


class UpdateThread : public QThread {
    Q_OBJECT

    StringListModel *mMyClass;

public:
    UpdateThread(StringListModel * myClass);
protected:
    void run();
};

=== 自定义类.cpp ===

StringListModel::StringListModel(QObject *parent) : QAbstractListModel(parent)
{
    stringList << "one" << "two" << "three";
    QThread *thread = new UpdateThread(this);
    thread->start();
}

int StringListModel::rowCount(const QModelIndex &parent) const
{
    return stringList.count();
}

QVariant StringListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (index.row() >= stringList.size())
        return QVariant();

    if (role == Qt::UserRole + 1)
        return stringList.at(index.row());
    else
        return QVariant();
}

QHash<int, QByteArray> StringListModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[Qt::UserRole + 1] = "title";

    return roles;
}
void StringListModel::newItem()
{
    qDebug() << "size: " << stringList.size();
    beginResetModel();
    stringList << "new";
    endResetModel();
}

UpdateThread::UpdateThread(StringListModel * myClass)
{
    mMyClass = myClass;
}

void UpdateThread::run()
{
    while (true) {
        mMyClass->newItem();
        msleep(1000);
    }
}
4

1 回答 1

0

您尽职尽责地忽略了同步访问模型的问题。当您拥有从多个线程访问的任何对象时(即使是像原始指针这样“简单”的东西),您必须处理这种访问的后果。

我建议你不要乱用线程,除非你有测量表明你会受益。

于 2013-10-26T14:56:17.460 回答