自定义 listModel 不通知视图 [英] Custom listModel does not notify the view

查看:34
本文介绍了自定义 listModel 不通知视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的自定义列表模型,我在其中放置了应该在 QML 视图上显示的数据.但是由于某种原因,QML 中的视图有时会正常更新,有时会使用以前的数据,有时不会进行更新.

I have my custom list model where I put data which should be displayed on the QML view. But for some kind of reason the view in QML sometimes is updated normally, sometimes with previous data and sometimes updating is not performed.

这是我填充模型的函数 - 这个函数是从其他线程调用的.

Here is the function where I fill the model - this function is called from some other thread.

void MyScreen::fillListModel()
{
    const QString SEPARATOR = " ";   
    myListModel->resetModel();

    for (int i = 0; i < MAX_ROWS; ++i)
    {
        QString key = QString::fromUtf16(MyData::getParameterKey(i).c_str());
        QString val = QString::fromUtf16(MyData::getParameterVal(i).c_str());       
        myListModel->addItem(key + SEPARATOR + val);
    }
}

模型重置的实现:

void BrowsingModelBase::resetModel()
{
    beginResetModel();
    m_items.clear();
    endResetModel();
}

addItem() 的实现:

void BrowsingModelBase::addItem(const BrowsingItemModelBase &item)
{
    int count = m_items.size();
    beginInsertRows(QModelIndex(), count, count);
    m_items.append(item);
    endInsertRows();
}

最后是我的 QML 文件:

Finally my QML file:

MyScreen {

    Column {
        id: myFlowList
        y: 110
        x: 220

        ListView {
            height:1000
            spacing: 35;

            model: myListModelRoot.myListModel

            delegate: Text {
                text: text1
            }
        }
    }
}

奇怪的是 after loop with line

The strange thing is that after loop with line

myListModel->addItem(key + SEPARATOR + val);

当我使用来自 myListModel 的数据打印日志时,它会填充正确的数据,但视图通常会使用以前的数据进行更新.数据更改信号是否可能卡在某处?知道解决方案是什么吗?

when I print logs with data from myListModel it is filled with proper data, but the view is usually updated with previous data. Is it possible that data change signal is stuck somewhere? Any idea what is the solution?

推荐答案

问题很可能是因为您不是从主 GUI 线程调用 fillListModel() 方法.您可以从其他线程更新模型,但 beginResetModel();, endResetModel();, beginInsertRows(QModelIndex(), count, count);... 方法必须在主 GUI 线程中调用.

The problem is most likely the fact that you are calling the fillListModel() method not from the main GUI thread. You can update the model from other threads but the beginResetModel();, endResetModel();, beginInsertRows(QModelIndex(), count, count);... methods have to be called in the main GUI thread.

在 GUI 线程中调用这些方法的一种方法(可能不是最有效的)是:

One way to call these method in GUI thread (maybe not the most efficient) is to :

  1. 为您要调用的每个方法创建信号:

  signals:
    //these signals are emitted from worker thread
    void requestBeginResetModel();
    void requestEndResetModel();

  1. 创建实际调用方法的槽:

  private slots:
    //these slots execute the model reset operations in main thread
    void callBeginResetModel();
    void callEndResetModel();

  1. 连接信号和插槽:

  //connect the appropriate signals
  connect(this, SIGNAL(requestBeginResetModel()),
          this, SLOT(callBeginResetModel()));
  connect(this, SIGNAL(requestEndResetModel()),
          this, SLOT(callEndResetModel()));

  1. 您的重置模型将是:

void BrowsingModelBase::resetModel()
{
    emit requestBeginResetModel();
    m_items.clear();
    emit requestEndResetModel();
}

  1. 最后,插槽实现为:

void ObjectModel::callBeginResetModel()
{
  beginResetModel();
}

void ObjectModel::callEndResetModel()
{
  endResetModel();
}

请注意,您也必须对行插入方法执行相同的操作.或者,您可以在发出的信号之间的 resetModel() 方法中填充模型.

Note that you will have to do the same for row insert methods as well. Or alternatively you could fill you model in the resetModel() method in between emitted signals.

这篇关于自定义 listModel 不通知视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆