How to stop calling data() function for the child items in a tree view initially
Hi,
I am implementing a tree view where initially I am showing all the parents, all the child items are collapsed.
but when initially I show my tree view, data() function is calling for all the items which are collapsed(childs) also.
How to prevent the data function calling for collapsed child items also, I want my data function to be called only for the items which are visible.
I have customized QAbstractItemModel, QTreeView and using them.
Thanks in advance.
Re: How to stop calling data() function for the child items in a tree view initially
Quote:
Originally Posted by
DURGAPRASAD NEELAM
I have customized QAbstractItemModel, QTreeView and using them.
How are we supposed to help if we don't know what you had customized?
Re: How to stop calling data() function for the child items in a tree view initially
I have re-implemented below functions in my model.
Code:
QVariant headerData
( int section, Qt
::Orientation orientatio,
int role
= Qt
::DisplayRole ) const;
And I am using proxy model too for filtering data, here i re-implement filterAcceptsRow().
If more info is needed, Please let me know.
Thnaks.
Re: How to stop calling data() function for the child items in a tree view initially
Yes, more info is needed :)
Re: How to stop calling data() function for the child items in a tree view initially
here is the implementation Part of Model.
if more info is needed, Please let me know exactly what is needed :-)
Note : Entire implementation (model, Item) is from Sample tree model example in Qt only (It fits for my requirement so, I just edited that example)
//proxy
Code:
{
setDynamicSortFilter( false );
}
ProxyModel::~ProxyModel()
{
}
bool ProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
return filterLogic();
}
//Model
Code:
Model::Model(const QList<QList<QVariant> > &lines,const QList<int>& positions)
{
QList<QVariant> rootData;
m_rootItem = new Item( rootData );
setupModelData( lines, positions, m_rootItem );
}
Model::~Model()
{
delete m_rootItem;
}
Item* Model::getRootItem() const
{
return m_rootItem;
}
{
if ( ! index.isValid() )
Item *item = static_cast<Item*>( index.internalPointer() );
switch( role )
{
case Qt::DisplayRole:
{
return item->data( index.column(),Qt::DisplayRole );
break;
}
}
}
{
if (( role != Qt::EditRole && role != Qt::DecorationRole && role != Qt::ForegroundRole && role != Qt::BackgroundRole ) || !index.isValid() )
return false;
/* Get the item of this index */
Item *item = static_cast<Item*>( index.internalPointer() );
/* Editing this item */
bool result = item->setData(index, value, role);
if (result)
emit dataChanged( index, index );
return result;
}
Qt
::ItemFlags Model
::flags( const QModelIndex &index
) const{
if ( ! index.isValid() )
return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant Model
::headerData( int section, Qt
::Orientation orientation,
int role
) const {
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
{
return m_rootItem->data( section,Qt::DisplayRole );
}
}
{
if ( ! hasIndex(row, column, parent) )
Item *parentItem;
if ( ! parent.isValid() )
parentItem = m_rootItem;
else
parentItem = static_cast<Item*>( parent.internalPointer() );
Item *childItem = parentItem->child( row );
if ( childItem )
return createIndex( row, column, childItem );
else
}
{
if ( ! index.isValid() )
Item *childItem = static_cast<Item*>( index.internalPointer() );
Item *parentItem = childItem->parent();
if ( parentItem == m_rootItem )
if( parentItem == NULL )
{
}
return createIndex( parentItem->row(), 0, parentItem );
}
{
Item *parentItem;
if ( parent.column() > 0 )
return 0;
if ( ! parent.isValid() )
parentItem = m_rootItem;
else
parentItem = static_cast<Item*>( parent.internalPointer() );
return parentItem->childCount();
}
bool Model
::hasChildren ( const QModelIndex & parent
) const {
Item *parentItem;
if ( parent.column() > 0 )
return false;
if ( ! parent.isValid() )
parentItem = m_rootItem;
else
parentItem = static_cast<Item*>( parent.internalPointer() );
return parentItem->hasChildren();
}
void Model::setupModelData(const QList<QList<QVariant> >& lines, const QList<int>& positions, Item *parent)
{
//same logic from Sample tree example in Qt
}
Re: How to stop calling data() function for the child items in a tree view initially
If you want to nail down the problem then get rid of all elements that do not change the test result. If it still doesn't work without a proxy model then remove it from the equation and repeat the test. Find a minimal compilable example reproducing the problem. You said you modified the view and the model. Can you reproduce the problem using a custom model with a standard view? How about a standard model and customized view?
Re: How to stop calling data() function for the child items in a tree view initially
hmm.. I will try those things and let you know the result.
mean while, with your experience do you have any idea or can you suspect any of the functions which might cause for this problem.
Note :: I am doing some another thing in Data actually, Will this cause any problem ??
Code:
{
if ( ! index.isValid() )
Item *item = static_cast<Item*>( index.internalPointer() );
switch( role )
{
case Qt::DisplayRole:
{
//initially i am getting data which is needed for building empty tree, then i am populating that empty tree
// on demand, when data function called I am reading data from Data base and updating Item data and then reading it
1. read data from data base //read one row from db
2. item->setData(data); // update that data to item
//then read ite
return item->data( index.column(),Qt::DisplayRole );
break;
}
}
}
Re: How to stop calling data() function for the child items in a tree view initially
Re: How to stop calling data() function for the child items in a tree view initially
I could not found a reason for this problem, so I have implemented a logic
1. if data is called for an item, I am checking weather it is child or not, if it is child item then I am checking its parent is expanded or not
If it parent is expanded then I am firing a query to read a data from data base otherwise not firing a query as we are not showing it in a view (item is collapsed).
2. when we expand an item, data function should be called then I am again I am checking parent is expanded or no, this time it will be true then I am firing a query and getting data.
But strangely When I expand an item (Click on + sign ), data() function will not be calling at all :-(
When I remove proxy model then data function is calling (when clicks on + sign).
What is this strange behavior, why data function is not calling when proxy is there in above case ??
Code:
{
if ( ! index.isValid() )
TreeItem *item = static_cast<TreeItem*>( index.internalPointer() );
switch( role )
{
case Qt::DisplayRole:
{
TreeItem* l_parent = item->parent(); //parent item
bool l_getData = true;
if(m_rootItem == l_parent) // if top most item then we should read data
{
l_getData = true;
}
else if(l_parent && !l_parent->isExpanded()) //if its not top most item and its parent is not expanded, no need to read data
{
l_getData = false;
}
if(l_getData && !item->isDataUpdated()) // if data need to be read
{
ReadRowFromDb(index); // read from Data base & update item
}
return item->data( index.column(),Qt::DisplayRole ); // then read data from item
}
}
}
Re: How to stop calling data() function for the child items in a tree view initially
Quote:
What is this strange behavior, why data function is not calling when proxy is there in above case ??
Most likely you have not implemented the mapping functions in your proxy model, or you have implemented them incorrectly. Did you implement the data() method in the proxy?
Re: How to stop calling data() function for the child items in a tree view initially
The only function I have implemented in customized QSortFilterProxyModel is filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const.
I have not implemented the data() function.
What are the function I should to re implement while using proxy?
Thanks in Advance.
Re: How to stop calling data() function for the child items in a tree view initially
I have implemented data() in proxy too, still same issue.
Code:
{
if ( ! index.isValid() )
}
Re: How to stop calling data() function for the child items in a tree view initially
Try minimizing your example instead of throwing in more and more code. Can you reproduce the issue with a bare standard item model and a bare QTreeView?
Re: How to stop calling data() function for the child items in a tree view initially
When I tried using with QTreeView only, data function is calling as expected.
Re: How to stop calling data() function for the child items in a tree view initially
Quote:
Originally Posted by
DURGAPRASAD NEELAM
When I tried using with QTreeView only, data function is calling as expected.
So please show your customizations to the view.
Re: How to stop calling data() function for the child items in a tree view initially
Below is the code for view. (there is lot of other c++ code in view, but typical qt related stuff in view is this much)
Code:
MyView
::MyView ( Model
* treeModel
) : QTreeView(parent
){
setContextMenuPolicy( Qt::DefaultContextMenu );
installEventFilter( this );
m_proxyTreeModel = new ProxyModel( this ); // proxy model:
m_proxyTreeModel->setSourceModel( m_treeModel ); // tree model created in viewer:
m_proxyTreeModel->setDynamicSortFilter(true);
setModel( m_proxyTreeModel );
setAllColumnsShowFocus( true );
setUniformRowHeights( true );
}
Re: How to stop calling data() function for the child items in a tree view initially
This is not your real code. This wouldn't even compile. Even if it did, it would crash when ran. And you were supposed to use a standard model against your custom view. Without any proxy models inbetween.