Setting First Column Spanned to align child treeview with parent row takes long time and freezes main thread
-
In my Qt project, I've created a custom tree view. Another custom treeview is the child of each row in that treeview. I'm using "setFirstColumnSpanned" to align the child treeview with the parent row's viewport, however doing so for a huge dataset takes a long time and causes the main thread to freeze.
This is the driver code:
childtv = new CustomTreeviewClass(); childtv->SetParentIndex(parentIndex); QStandardItemModel *Model = new QStandardItemModel(); childtv->setModel(Model); QStandardItem *childItem = new QStandardItem; ui->treevRadar->AddTreeView(ParentItem,ui->treevRadar,childItem,childtv);This is where I add new TreeView:
void CustomTreeviewClass::AddTreeView(QStandardItem *parentItem, QTreeView *ParentTv, QStandardItem *childItem, QTreeView *ChildTv) { const int WidgetRole = Qt::UserRole + 1; parentItem->setChild(0, childItem); childItem->setData(QVariant::fromValue(static_cast<void*>(ChildTv)), WidgetRole); ParentTv->setIndexWidget(childItem->index(), ChildTv); ParentTv->setFirstColumnSpanned(childItem->index().row(), parentItem->index(), true); }I tried commenting the following line:
ParentTv->setFirstColumnSpanned(childItem->index().row(), parentItem->index(), true);And then doing the following in a slot invoked by triggering
expandedsignal of QTreeView:void WindowClass::OnExpand(const QModelIndex &index) { if(index.isValid()) { QStandardItemModel *model = (QStandardItemModel *)index.model(); QStandardItem *item = model->item(index.row(), 1); if(mmap_Child .contains(item->text().toLongLong())) { ui->treevRadar->setFirstColumnSpanned(mmap_Child.value(item->text().toLongLong())->index().row(), mmap_Child.value(item->text().toLongLong())->parent()->index(), true); } } }The
mmap_Childis a private member map that keeps track of the child tree views for all the rows.
This kinda works but I'll have to do the same in every other window that I use the custom treeview in.Is there a better solution to this?
-
In my Qt project, I've created a custom tree view. Another custom treeview is the child of each row in that treeview. I'm using "setFirstColumnSpanned" to align the child treeview with the parent row's viewport, however doing so for a huge dataset takes a long time and causes the main thread to freeze.
This is the driver code:
childtv = new CustomTreeviewClass(); childtv->SetParentIndex(parentIndex); QStandardItemModel *Model = new QStandardItemModel(); childtv->setModel(Model); QStandardItem *childItem = new QStandardItem; ui->treevRadar->AddTreeView(ParentItem,ui->treevRadar,childItem,childtv);This is where I add new TreeView:
void CustomTreeviewClass::AddTreeView(QStandardItem *parentItem, QTreeView *ParentTv, QStandardItem *childItem, QTreeView *ChildTv) { const int WidgetRole = Qt::UserRole + 1; parentItem->setChild(0, childItem); childItem->setData(QVariant::fromValue(static_cast<void*>(ChildTv)), WidgetRole); ParentTv->setIndexWidget(childItem->index(), ChildTv); ParentTv->setFirstColumnSpanned(childItem->index().row(), parentItem->index(), true); }I tried commenting the following line:
ParentTv->setFirstColumnSpanned(childItem->index().row(), parentItem->index(), true);And then doing the following in a slot invoked by triggering
expandedsignal of QTreeView:void WindowClass::OnExpand(const QModelIndex &index) { if(index.isValid()) { QStandardItemModel *model = (QStandardItemModel *)index.model(); QStandardItem *item = model->item(index.row(), 1); if(mmap_Child .contains(item->text().toLongLong())) { ui->treevRadar->setFirstColumnSpanned(mmap_Child.value(item->text().toLongLong())->index().row(), mmap_Child.value(item->text().toLongLong())->parent()->index(), true); } } }The
mmap_Childis a private member map that keeps track of the child tree views for all the rows.
This kinda works but I'll have to do the same in every other window that I use the custom treeview in.Is there a better solution to this?
@ScleaverZer0ne
This is only a guess/think out loud. I assume it take a long time, with a large dataset, because it is figuring out how wide each child treeview (recursively?) is, and that's really heavy> Is it calling it more than once for a given treeview? I am thinking/wondering whether it just needs the child'sQWidget::sizeHint()? Could you calculate/set this once and re-use it for children if they are queried multiple times? -
@ScleaverZer0ne
This is only a guess/think out loud. I assume it take a long time, with a large dataset, because it is figuring out how wide each child treeview (recursively?) is, and that's really heavy> Is it calling it more than once for a given treeview? I am thinking/wondering whether it just needs the child'sQWidget::sizeHint()? Could you calculate/set this once and re-use it for children if they are queried multiple times?@JonB Each parent treeview only has one child treeview, and each child treeview of each parent has the same width (the height depends on the dataset size, which in some situations will be extremely enormous, but that is determined after all the children have been assigned to the parents).
Can you please elaborate this??
I am thinking/wondering whether it just needs the child's
QWidget::sizeHint()? Could you calculate/set this once and re-use it for children if they are queried multiple times? -
@JonB Each parent treeview only has one child treeview, and each child treeview of each parent has the same width (the height depends on the dataset size, which in some situations will be extremely enormous, but that is determined after all the children have been assigned to the parents).
Can you please elaborate this??
I am thinking/wondering whether it just needs the child's
QWidget::sizeHint()? Could you calculate/set this once and re-use it for children if they are queried multiple times?@ScleaverZer0ne
For the childQTreeView, if you have not already done so subclass.- Override
virtual QSize sizeHint() constto return some fixed size, e.g.QSize(400, 400). - You may also need to override
QSize QAbstractItemView::sizeHintFor...()methods too, not sure. - Add
setSizePolicy(QSizePolicy::Fixed)on it.
Now does that affect your "takes a long time and causes the main thread to freeze"? If yes then we are onto something, if no then this guess is not the reason.
- Override
-
@ScleaverZer0ne
For the childQTreeView, if you have not already done so subclass.- Override
virtual QSize sizeHint() constto return some fixed size, e.g.QSize(400, 400). - You may also need to override
QSize QAbstractItemView::sizeHintFor...()methods too, not sure. - Add
setSizePolicy(QSizePolicy::Fixed)on it.
Now does that affect your "takes a long time and causes the main thread to freeze"? If yes then we are onto something, if no then this guess is not the reason.
@JonB Sorry for the late response.
I tried overriding
virtual QSize sizeHint() constas you suggested but that didn't do much. I also set the size policy for the child treeview to fixed width & min expanding height. The behavior is still the same. - Override
-
@JonB Sorry for the late response.
I tried overriding
virtual QSize sizeHint() constas you suggested but that didn't do much. I also set the size policy for the child treeview to fixed width & min expanding height. The behavior is still the same.@ScleaverZer0ne
OK, I had hoped/guessed that your "takes long time and freezes main thread" might have been from having to evaluate child sub-tree to determine size.I don't know then. If it were me I would probably keep playing till I found out what was causing the delay/freeze, but that's up to you.