【问题标题】:QSortFilterProxyModel with QStandardItemModel after appendRow are not workingappendRow 之后带有 QStandardItemModel 的 QSortFilterProxyModel 不起作用
【发布时间】:2012-07-30 06:07:39
【问题描述】:

这是我得到的:

  • QTreeView 小部件 (*);
  • 源模型MainModel 继承自QStandardItemModel。没有重新实现虚拟data() const 方法;
  • 代理MainFilterProxyModel继承自QSortFilterProxyModel

树:

[PERIOD 1]
   [CHILD 1]
   [CHILD 2]
      [SUBCHILD 2.1]
      ...
   [CHILD N]
[PERIOD 2]
...
[PERIOD N]

因此,当我尝试添加类似 (**) 代码的 CHILD-row 时,主要问题就出现了。过滤器代理模型,文档添加到源模型后,不知道新行,也没有在树上显示。

我确定代理在appendRow 方法执行其工作时没有从QStandardItemModel 获得信号,因此代理无法过滤新行,也没有使其可见。

有什么帮助吗?

谢谢。

PS:如果我关闭代理,一切都很好。但问题不在于代理。代理只是没有得到关于附加到主源模型的新行的信号......


(*) 这里是QTreeView

MainView::MainView( QWidget* parent /* = 0 */ ) : QTreeView( parent )
{
     if( !model_ )
     {
          model_ = new MainModel( this );
     }

     if( !proxy_ )
     {
          proxy_ = new MainFilterProxyModel( this );
          proxy_->setDynamicSortFilter( true );
          proxy_->setSourceModel( model_ );

          setModel( proxy_ );
     }
}

(**) 这是我的追加函数

void MainModel::addRow( const DocumentPtr& document, QStandardItem* parentItem )
{
     assert( document );

     QList< QStandardItem* > items;
     items << ( new QStandardItem );
     items << ( new QStandardItem );
     items << ( new QStandardItem );
     items << ( new QStandardItem );
     items << ( new QStandardItem );
     items << ( new QStandardItem );
     items << ( new QStandardItem );

     updateRow( document, items );

     if( !parentItem )
     {
          BOOST_FOREACH( const TimePeriod& period, TimePeriod::all() )
          {
               if( period.contains( QDateTime::fromTime_t( document->creationDate() ) ) )
               {
                    QStandardItem* periodItem = itemByPeriod( period );
                    Q_ASSERT( periodItem );

                    periodItem->appendRow( items );

                    break;
               }
          }
     }
     else
     {
          parentItem->appendRow( items );
     }
}

【问题讨论】:

  • 在给出的示例中,您不是将项目附加到模型,而是附加到 QStandardItems,您以在示例中不可见的方式获得这些项目。你能简化你的代码,让它完全被看到并且仍然可以重现故障吗?
  • @vtmarvin 我不太明白我要做什么,但我把源文件放在这里:pastebin.com/RMLqHZhS希望有帮助!
  • 好吧,如果你连MainFilterProxyModel的代码都不显示,那我们怎么看它为什么没有收到信号呢?
  • @nus 你是对的。这是代理标头(pastebin.com/pjYsLVs4)和源(pastebin.com/udTPS0c6)文件...
  • @mosg 我仍然无法按照您的程序流程进行操作,因为缺少 main-model.h。什么是模型_和代理_?他们是数据成员吗?您是否尝试将自定义代理替换为标准代理,只是为了查看错误是在您的代理中还是在您的主模型中?

标签: qt qt4 qstandarditemmodel qsortfilterproxymodel


【解决方案1】:

建模的基类是QAbstractItemModel。最好使用抽象类的方法来做你想做的事。 QStandardItemModelQAbstractItemModel 抽象方法的简单实现,大部分QStandardItemModel 新方法被重新实现的抽象函数使用。下面是使用抽象类方法添加项和子项的代码:

QAbstractItemModel * pModel = new QStandardItemModel(parent);

int nRows = pModel->rowCount();
pModel->insertRow(nRows); // this will emit rowsAboutToBeInserted() and rowsInserted() signals
pModel->insertColumn(0); // this will emit columnsAboutToBeInserted() and columnsInserted() signals
const QModelIndex indexFirstItem = pModel->index(nRows, 0);
pModel->setData(indexFirstItem, "Item text"); // this will emit dataChanged() signal
int nChildRows = pModel->rowCount(indexFirstItem);
pModel->insertRow(nChildRows, indexFirstItem); // this will emit rowsInserted()
pModel->insertColumn(0, indexFirstItem); // we also need to do this for the item's children
const QModelIndex indexChild = pModel->index(nChildRows, 0, indexFirstItem);
pModel->setData(indexChild, "Child item text");

如果我们尝试使用 QStandardItemModel 方法做同样的事情,它将看起来像:

QStandardItemModel *pModel = new QStandardItemModel(parent);
QStandardItem *pItem = new QStandardItem("Item text");
pItem->appendRow(new QStandardItem); // pItem is not yet added to pModel and rowsInserted won't be emitted
pModel->appendRow(pItem); // this will probably emit rowsInserted() signal but since we set tha text of the item when creating the pItem the dataChanged() signal won't be emitted.

因此,如果您使用pItem-&gt;appendRow() 添加子项目并且pItem 尚未添加到模型中,您可能不会收到rowsInserted() 信号,因此不会通知代理模型。根据我的经验,第一种方法效果更好,并且更健壮,尽管您需要编写几行额外的代码。直接使用QStandardItemModel 方法通常会以丢失信号或其他问题而告终。您只需查看QAbstractItemModelQModelIndex 文档即可。

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多