C++ 在QabstracteView中通知更改的最佳方式是什么

C++ 在QabstracteView中通知更改的最佳方式是什么,c++,qt,qabstractitemmodel,C++,Qt,Qabstractitemmodel,我有一个QListView,它的模型(源自QabstracteModel)根据UI中的一些条件定期更改。当当前模型更新或模型更改时,视图本身认为新行已添加/删除时,我希望收到通知。我需要此通知,以便调用setIndexWidget并在特定列下添加自定义控件。我不希望重复调用setIndexWidget,因为该小部件的数量非常昂贵。因此,每行一次将是理想的 我尝试了rowsInserted/rowsAboutToBeRemoved和dataChanged,但如果要设置到视图中的模型中已经有项,则不

我有一个QListView,它的模型(源自QabstracteModel)根据UI中的一些条件定期更改。当当前模型更新或模型更改时,视图本身认为新行已添加/删除时,我希望收到通知。我需要此通知,以便调用setIndexWidget并在特定列下添加自定义控件。我不希望重复调用setIndexWidget,因为该小部件的数量非常昂贵。因此,每行一次将是理想的

我尝试了rowsInserted/rowsAboutToBeRemoved和dataChanged,但如果要设置到视图中的模型中已经有项,则不会调用这些


如果您有任何想法,我们将不胜感激。

您对
数据更改的看法是错误的。如果任何数据项的内容发生更改,则会发出
dataChanged
信号。假设
dataChanged
插槽连接到模型上的同一信号,以下不变量保持不变

class ... : public QObject {
  QModelIndex m_index;
  bool m_changed;
  Q_SLOT void dataChanged(const QModelIndex & tl) {
    m_changed = m_changed || tl == m_index;
  }
  ...
};  

m_index = QModelIndex(...);
QVariant before, after;
m_changed = false;
before = model->data(index);
after = model->data(index);
Q_ASSERT(before == after || m_changed);
您所描述的内容很可能是由模型的错误行为引起的。有一个模型测试套件可以用来验证模型是否符合所需的不变量

具体解决您的问题:

  • 当视图本身认为在当前模型更新时添加/删除了新行时,我希望收到通知

    观点不需要相信任何东西。您的模型必须发出相应的信号。只需从一些
    QObject
    连接到这些信号。这就是视图所做的一切。如果信号没有发出,视图将不会得到通知。故事结束了

  • 。。。或者当模型改变时

    因为整个模型都换了,所以没有信号。您是在视图中调用
    setModel
    的人,所以这应该不是问题。你最好知道什么时候打电话:)


  • 关于
    数据更改
    ,您错了。如果任何数据项的内容发生更改,则会发出
    dataChanged
    信号。假设
    dataChanged
    插槽连接到模型上的同一信号,以下不变量保持不变

    class ... : public QObject {
      QModelIndex m_index;
      bool m_changed;
      Q_SLOT void dataChanged(const QModelIndex & tl) {
        m_changed = m_changed || tl == m_index;
      }
      ...
    };  
    
    m_index = QModelIndex(...);
    QVariant before, after;
    m_changed = false;
    before = model->data(index);
    after = model->data(index);
    Q_ASSERT(before == after || m_changed);
    
    您所描述的内容很可能是由模型的错误行为引起的。有一个模型测试套件可以用来验证模型是否符合所需的不变量

    具体解决您的问题:

  • 当视图本身认为在当前模型更新时添加/删除了新行时,我希望收到通知

    观点不需要相信任何东西。您的模型必须发出相应的信号。只需从一些
    QObject
    连接到这些信号。这就是视图所做的一切。如果信号没有发出,视图将不会得到通知。故事结束了

  • 。。。或者当模型改变时

    因为整个模型都换了,所以没有信号。您是在视图中调用
    setModel
    的人,所以这应该不是问题。你最好知道什么时候打电话:)


  • 您确定在填充模型时没有替换它(使用不同的QBStractItemModel对象)导致与QListView的初始连接丢失吗?setModel不应该处理所有这些连接吗?如果连接到QListView的信号,setModel将正确处理。我试图找出问题的原因,我认为您直接连接到模型的信号,然后更改模型。在这种情况下,除非您在更改模型后更新了连接,否则将不再发送您的信号。您确定在填充模型时没有替换它(使用不同的QabstracteModel对象)导致您与QListView的初始连接丢失?setModel不应该处理所有这些连接吗?如果您连接到QListView的信号,setModel将正确处理这些连接。我试图找出问题的原因,我认为您直接连接到模型的信号,然后更改模型。在这种情况下,除非您在更改型号后更新了连接,否则将不再发送您的信号。但我的型号不会更改。如果我只是将静态模型分配给视图,为什么会调用dataChanged?我的意思是,这是我想要的行为,但它似乎不是这样工作的。你说模型被改变了。你真的在交换整个模型吗?我偶尔会用另一个调用setModel的模型交换模型。但是,在视图中设置的模型在视图中设置和未在视图中设置时可能会发生更改。他们也有可能根本不会改变,但我的模式不会改变。如果我只是将静态模型分配给视图,为什么会调用dataChanged?我的意思是,这是我想要的行为,但它似乎不是这样工作的。你说模型被改变了。你真的在交换整个模型吗?我偶尔会用另一个调用setModel的模型交换模型。但是,在视图中设置的模型在视图中设置和未在视图中设置时可能会发生更改。它们也有可能根本不会改变。