这是我得到的:QTreeView
小部件(*);
源模型MainModel
继承自QStandardItemModel
。没有重新实现虚拟的data() const
方法;
代理MainFilterProxyModel
从QSortFilterProxyModel
继承;
那个树:
[PERIOD 1]
[CHILD 1]
[CHILD 2]
[SUBCHILD 2.1]
...
[CHILD N]
[PERIOD 2]
...
[PERIOD N]
因此,主要问题是当我尝试添加(**)代码一样的CHILD行时。将文档添加到源模型之后,过滤器代理模型不知道新行,也没有在树上显示它。
我确定
QStandardItemModel
方法执行工作时,代理不会从appendRow
发出信号,因此代理无法过滤新行,也不会使其可见。有什么帮助吗?
谢谢。
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_ );
}
}
(**)这是我的append函数:
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
。最好使用抽象类的方法来执行所需的操作。 QStandardItemModel
是QAbstractItemModel
抽象方法的简单实现,并且大多数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
方法工作通常会因信号丢失或其他麻烦而结束。您只需要查看QAbstractItemModel
和QModelIndex
文档。关于qt - appendRow之后的带有QStandardItemModel的QSortFilterProxyModel不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11757657/