Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Setting First Column Spanned to align child treeview with parent row takes long time and freezes main thread
Forum Updated to NodeBB v4.3 + New Features

Setting First Column Spanned to align child treeview with parent row takes long time and freezes main thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 904 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ScleaverZer0neS Offline
    ScleaverZer0neS Offline
    ScleaverZer0ne
    wrote on last edited by
    #1

    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 expanded signal 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_Child is 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?

    JonBJ 1 Reply Last reply
    0
    • ScleaverZer0neS ScleaverZer0ne

      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 expanded signal 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_Child is 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?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @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's QWidget::sizeHint()? Could you calculate/set this once and re-use it for children if they are queried multiple times?

      ScleaverZer0neS 1 Reply Last reply
      0
      • JonBJ JonB

        @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's QWidget::sizeHint()? Could you calculate/set this once and re-use it for children if they are queried multiple times?

        ScleaverZer0neS Offline
        ScleaverZer0neS Offline
        ScleaverZer0ne
        wrote on last edited by
        #3

        @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?

        JonBJ 1 Reply Last reply
        0
        • ScleaverZer0neS ScleaverZer0ne

          @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?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @ScleaverZer0ne
          For the child QTreeView, if you have not already done so subclass.

          • Override virtual QSize sizeHint() const to 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.

          ScleaverZer0neS 1 Reply Last reply
          0
          • JonBJ JonB

            @ScleaverZer0ne
            For the child QTreeView, if you have not already done so subclass.

            • Override virtual QSize sizeHint() const to 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.

            ScleaverZer0neS Offline
            ScleaverZer0neS Offline
            ScleaverZer0ne
            wrote on last edited by
            #5

            @JonB Sorry for the late response.

            I tried overriding virtual QSize sizeHint() const as 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.

            JonBJ 1 Reply Last reply
            0
            • ScleaverZer0neS ScleaverZer0ne

              @JonB Sorry for the late response.

              I tried overriding virtual QSize sizeHint() const as 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.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @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.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved