gpt4 book ai didi

qt - QSortFilterProxyModel 与 QStandardItemModel 后 appendRow 不工作

转载 作者:行者123 更新时间:2023-12-04 13:34:02 29 4
gpt4 key购买 nike

这是我得到的:

  • 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 );
}
}

最佳答案

建模的基类是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->appendRow() 来添加子项,并且如果 pItem 尚未添加到模型中,您可能不会获得 rowsInserted() 信号,因此不会通知代理模型。根据我的经验,第一种方法效果更好并且更健壮,尽管您需要多写几行。直接使用 QStandardItemModel 方法通常会以丢失信号或其他令人头疼的问题而告终。您只需查看 QAbstractItemModelQModelIndex 文档。

关于qt - QSortFilterProxyModel 与 QStandardItemModel 后 appendRow 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11757657/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com