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. QSplitter, how to change the widget of one side without resizing?

QSplitter, how to change the widget of one side without resizing?

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 3.0k 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.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by
    #1

    Hi,
    My use case is simple, I've an Horizontal Splitter, on the left side, I've a TreeView where a Model is displayed and on the right I've Editor that should be updated depending on the selected Item in the Model.
    So I'd like to be able to remove the right widget and replace it with another one and while doing this that the Splitter doesn't resize.
    how can I do that?
    If I delete the widget on the right, the Splitter resize...
    I've tried also to delete only the content of the right widget in order to refill the same one but this doesn't seem to work properly either...
    Any idea how I could achieve that?
    Cheers

    jsulmJ 1 Reply Last reply
    0
    • mbruelM mbruel

      Hi,
      My use case is simple, I've an Horizontal Splitter, on the left side, I've a TreeView where a Model is displayed and on the right I've Editor that should be updated depending on the selected Item in the Model.
      So I'd like to be able to remove the right widget and replace it with another one and while doing this that the Splitter doesn't resize.
      how can I do that?
      If I delete the widget on the right, the Splitter resize...
      I've tried also to delete only the content of the right widget in order to refill the same one but this doesn't seem to work properly either...
      Any idea how I could achieve that?
      Cheers

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @mbruel "I've tried also to delete only the content of the right widget in order to refill the same one but this doesn't seem to work properly either" - that's actualy what you should do. What did not work? Can you show the code?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • mbruelM Offline
        mbruelM Offline
        mbruel
        wrote on last edited by mbruel
        #3

        When I say it is not working properly it is because the splitter is moving when I change the widget.

        Here is what I've done:
        On my Mainwindow I've a QTreeView on the left, and on the right a QWidget called propertyEditor.

        Solution 1: keeping the same propertyEditor and deleting its content:

        MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            _ui(new Ui::MainWindow),
            _treeModel(new TreeModel()),
            _treeItemDelegate(new TreeItemDelegate()),
            _propertyLayout(new QVBoxLayout())
        {
            _ui->setupUi(this);
        
            _ui->treeView->setModel(_treeModel);
            _ui->treeView->setItemDelegate(_treeItemDelegate);
        
            _ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
            connect(_ui->treeView, &QWidget::customContextMenuRequested, this, &MainWindow::showCustomContextMenu);
        
            connect(_ui->treeView, &QAbstractItemView::clicked, this, &MainWindow::handleTreeClick);
        
            _ui->propertyEditor->setLayout(_propertyLayout);
        }
        
        void MainWindow::handleTreeClick(const QModelIndex &index)
        {
            TreeItem *item = static_cast<TreeItem*>(_treeModel->itemFromIndex(index));
            if (!item)
                return;
        
            switch(item->getType())
            {
            case (TreeItemType::TreeElementItem):
                clearPropertyWidget();
               _propertyLayout->addWidget(static_cast<TreeElemItem*>(item)->getElement()->createEditorWidget());
               break;
        
            default:
                clearPropertyWidget();
               break;
            }
        }
        
        void MainWindow::clearPropertyWidget()
        {
            qDebug() << "[MainWindow::clearPropertyWidget] nb items: " << _propertyLayout->count();
            while (_propertyLayout->count())
            {
                QLayoutItem *item = _propertyLayout->takeAt(0);
                if (item->widget())
                    delete item->widget();
                else if (item->layout())
                    delete item->layout();
            }
        }
        
        

        Solution 2: Deleting the propertyWidget and adding a new one in the Splitter each time

        void MainWindow::handleTreeClick(const QModelIndex &index)
        {
            TreeItem *item = static_cast<TreeItem*>(_treeModel->itemFromIndex(index));
            if (!item)
                return;
        
            switch(item->getType())
            {
            case (TreeItemType::TreeElementItem):
                clearPropertyWidget();
        
                _ui->propertyEditor = new QWidget();
                _propertyLayout = new QVBoxLayout();
                _ui->propertyEditor->setLayout(_propertyLayout);
        
               _propertyLayout->addWidget(static_cast<TreeElemItem*>(item)->getElement()->createEditorWidget());
               _ui->splitter->addWidget(_ui->propertyEditor);
               break;
        
            default:
                clearPropertyWidget();
               break;
            }
        }
        
        void MainWindow::clearPropertyWidget()
        {
                if (_propertyLayout)
                {
                    _ui->propertyEditor->hide();
                    delete _ui->propertyEditor;
                    _propertyLayout = nullptr;
                }
        }
        

        In both case, the Splitter is moving by itself when the propertyEditor is changing it's content or get empty.

        jsulmJ 1 Reply Last reply
        0
        • mbruelM mbruel

          When I say it is not working properly it is because the splitter is moving when I change the widget.

          Here is what I've done:
          On my Mainwindow I've a QTreeView on the left, and on the right a QWidget called propertyEditor.

          Solution 1: keeping the same propertyEditor and deleting its content:

          MainWindow::MainWindow(QWidget *parent) :
              QMainWindow(parent),
              _ui(new Ui::MainWindow),
              _treeModel(new TreeModel()),
              _treeItemDelegate(new TreeItemDelegate()),
              _propertyLayout(new QVBoxLayout())
          {
              _ui->setupUi(this);
          
              _ui->treeView->setModel(_treeModel);
              _ui->treeView->setItemDelegate(_treeItemDelegate);
          
              _ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
              connect(_ui->treeView, &QWidget::customContextMenuRequested, this, &MainWindow::showCustomContextMenu);
          
              connect(_ui->treeView, &QAbstractItemView::clicked, this, &MainWindow::handleTreeClick);
          
              _ui->propertyEditor->setLayout(_propertyLayout);
          }
          
          void MainWindow::handleTreeClick(const QModelIndex &index)
          {
              TreeItem *item = static_cast<TreeItem*>(_treeModel->itemFromIndex(index));
              if (!item)
                  return;
          
              switch(item->getType())
              {
              case (TreeItemType::TreeElementItem):
                  clearPropertyWidget();
                 _propertyLayout->addWidget(static_cast<TreeElemItem*>(item)->getElement()->createEditorWidget());
                 break;
          
              default:
                  clearPropertyWidget();
                 break;
              }
          }
          
          void MainWindow::clearPropertyWidget()
          {
              qDebug() << "[MainWindow::clearPropertyWidget] nb items: " << _propertyLayout->count();
              while (_propertyLayout->count())
              {
                  QLayoutItem *item = _propertyLayout->takeAt(0);
                  if (item->widget())
                      delete item->widget();
                  else if (item->layout())
                      delete item->layout();
              }
          }
          
          

          Solution 2: Deleting the propertyWidget and adding a new one in the Splitter each time

          void MainWindow::handleTreeClick(const QModelIndex &index)
          {
              TreeItem *item = static_cast<TreeItem*>(_treeModel->itemFromIndex(index));
              if (!item)
                  return;
          
              switch(item->getType())
              {
              case (TreeItemType::TreeElementItem):
                  clearPropertyWidget();
          
                  _ui->propertyEditor = new QWidget();
                  _propertyLayout = new QVBoxLayout();
                  _ui->propertyEditor->setLayout(_propertyLayout);
          
                 _propertyLayout->addWidget(static_cast<TreeElemItem*>(item)->getElement()->createEditorWidget());
                 _ui->splitter->addWidget(_ui->propertyEditor);
                 break;
          
              default:
                  clearPropertyWidget();
                 break;
              }
          }
          
          void MainWindow::clearPropertyWidget()
          {
                  if (_propertyLayout)
                  {
                      _ui->propertyEditor->hide();
                      delete _ui->propertyEditor;
                      _propertyLayout = nullptr;
                  }
          }
          

          In both case, the Splitter is moving by itself when the propertyEditor is changing it's content or get empty.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @mbruel You could try different values for sizePolicy property in the right widget (maybe Ignored?).

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • mbruelM Offline
            mbruelM Offline
            mbruel
            wrote on last edited by
            #5

            I've set both my left QTreeView and the right QWidget with a Fixed size policy and add them both a minimum Size and that seems to solve the resizing issue.

            There is just a little thing that still annoys me: I can move the slider left or right until I reach the minimum size of the widgets but if I continue to slide until the limit one of the widget will take the whole area and the other one will disappear.
            Is there a way to block this behaviour?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              Use QSplitter::setCollapsible on your widgets and you should be good to go.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              2
              • mbruelM Offline
                mbruelM Offline
                mbruel
                wrote on last edited by
                #7

                Cool thanks for this :)
                Last little thing: when I'm reducing my treeview, instead of having straight away the scrollbar of the QScrollArea containing the TreeView, first the Text of my TreeItems is truncated with ...
                How can I stop this behaviour?

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  You might have to implement a custom QStyledItemDelegate and customise the QStyleOptionViewItem and disable the QStyleOptionViewItem::WrapText option.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • mbruelM Offline
                    mbruelM Offline
                    mbruel
                    wrote on last edited by
                    #9

                    The WrapText Option was already disabled (myOption.features.testFlag(QStyleOptionViewItem::WrapText) returns false)
                    By digging a little bit in QStyleOptionViewItem, I've found the attribute I'm interested in:

                    myOption.textElideMode = Qt::ElideNone;
                    

                    However I'm still not having my desired behaviour.
                    My Widget is a QSplitter with on the left a QTreeView and on the Right a QScrollArea with a custom widget.
                    When I decrease the area of the QTreeView, the Scrollbar is not kicking in as soon as the Text of some Items can't be displayed entirely.
                    I've tried to put a _ui->treeView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) but it doesn't change anything.
                    I've also tried to put my QTreeView inside a QScrollArea but this wouldn't work also and I would see 2 scrollbars.

                    So what I would like is to stop the ElideMode and thus that the ViewPort of the QTreeView kicks in as soon as some Item would have been elided.
                    Any idea how to achieve that?
                    Cheers

                    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