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. Move QScrollArea between QWidgets
Forum Updated to NodeBB v4.3 + New Features

Move QScrollArea between QWidgets

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 2 Posters 1.4k 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.
  • M Offline
    M Offline
    Mark81
    wrote on last edited by Mark81
    #1

    As a follow-up of an old thread, I need to move a QScrollArea, that is a page of QTabBar, to a QDialog. This code shows an empty dialog:

    void MainWindow::createTabs(QStringList names)
    {
        foreach (QString name, names)
        {
            QWidget widget = new QWidget();
            QScrollArea *scrollArea = new QScrollArea();
            scrollArea->setWidgetResizable(true);
            scrollArea->setWidget(widget);
            // [...] populate widget with items
            ui->tabView->addTab(scrollArea, name); 
        }
    }
    
    void MainWindow::tabView_tabCloseRequested(int index)
    {
        QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); // "save" the tab's widget
        ui->tabView->removeTab(index);
    
        QDialog *dialog = new QDialog(this);
        QVBoxLayout *layoutDialog = new QVBoxLayout();
        layoutDialog->addWidget(area); // "restore" the widget into the dialog
        dialog->setLayout(layoutDialog);
    
        dialog->show();
    }
    

    Instead, if I set the dialog's layout to area->layout() I get the contents but without the QScrollArea.
    Why adding the QScrollArea itself to the new layout doesn't show the contents?

    jsulmJ 1 Reply Last reply
    0
    • M Mark81

      As a follow-up of an old thread, I need to move a QScrollArea, that is a page of QTabBar, to a QDialog. This code shows an empty dialog:

      void MainWindow::createTabs(QStringList names)
      {
          foreach (QString name, names)
          {
              QWidget widget = new QWidget();
              QScrollArea *scrollArea = new QScrollArea();
              scrollArea->setWidgetResizable(true);
              scrollArea->setWidget(widget);
              // [...] populate widget with items
              ui->tabView->addTab(scrollArea, name); 
          }
      }
      
      void MainWindow::tabView_tabCloseRequested(int index)
      {
          QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); // "save" the tab's widget
          ui->tabView->removeTab(index);
      
          QDialog *dialog = new QDialog(this);
          QVBoxLayout *layoutDialog = new QVBoxLayout();
          layoutDialog->addWidget(area); // "restore" the widget into the dialog
          dialog->setLayout(layoutDialog);
      
          dialog->show();
      }
      

      Instead, if I set the dialog's layout to area->layout() I get the contents but without the QScrollArea.
      Why adding the QScrollArea itself to the new layout doesn't show the contents?

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

      @Mark81 said in Move QScrollArea between QWidgets:

      QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); // "save" the tab's widget
      ui->tabView->removeTab(index);

      You did not even check whether you actually succeeded in getting the scroll area. Also, it could be that after removeTab the scroll area is deleted. You should at least check whether area is a valid pointer and if it is set parent to null to prevent it from being deleted if its parent is deleted.

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

      M 1 Reply Last reply
      1
      • jsulmJ jsulm

        @Mark81 said in Move QScrollArea between QWidgets:

        QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); // "save" the tab's widget
        ui->tabView->removeTab(index);

        You did not even check whether you actually succeeded in getting the scroll area. Also, it could be that after removeTab the scroll area is deleted. You should at least check whether area is a valid pointer and if it is set parent to null to prevent it from being deleted if its parent is deleted.

        M Offline
        M Offline
        Mark81
        wrote on last edited by
        #3

        @jsulm said in Move QScrollArea between QWidgets:

        You did not even check whether you actually succeeded in getting the scroll area. Also, it could be that after removeTab the scroll area is deleted. You should at least check whether area is a valid pointer

        mmm... the docs says the page is not actually deleted after removing it:

        Removes the tab at position index from this stack of widgets. The page widget itself is not deleted.

        In my case the page widget is QScrollArea.
        Anyway, now I've checked the validity of area:

        QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index));
        qDebug() << area;
        ui->tabView->removeTab(index);
        qDebug() << area;
        

        QScrollArea(0x332d2b78)
        QScrollArea(0x332d2b78)

        @jsulm said:

        and if it is set parent to null to prevent it from being deleted if its parent is deleted.

        assigning a QWidget to a QLayout doesn't re-parent it?
        Anyway:

        qDebug() << area->parent();
        QVBoxLayout *layoutDialog = new QVBoxLayout();
        layoutDialog->addWidget(area);
        qDebug() << area->parent();
        dialog->setLayout(layoutDialog);
        

        QStackedWidget(0x333eda38, name = "qt_tabwidget_stackedwidget")
        QStackedWidget(0x333eda38, name = "qt_tabwidget_stackedwidget")

        So it seems not - I must remember it wrong.
        I did this:

        qDebug() << area->parent();
        QVBoxLayout *layoutDialog = new QVBoxLayout();
        layoutDialog->addWidget(area);
        area->setParent(dialog);
        qDebug() << area->parent();
        dialog->setLayout(layoutDialog);
        

        QStackedWidget(0x3330da38, name = "qt_tabwidget_stackedwidget")
        QDialog(0x34551b10)

        but still the dialog is empty.

        jsulmJ 1 Reply Last reply
        0
        • M Mark81

          @jsulm said in Move QScrollArea between QWidgets:

          You did not even check whether you actually succeeded in getting the scroll area. Also, it could be that after removeTab the scroll area is deleted. You should at least check whether area is a valid pointer

          mmm... the docs says the page is not actually deleted after removing it:

          Removes the tab at position index from this stack of widgets. The page widget itself is not deleted.

          In my case the page widget is QScrollArea.
          Anyway, now I've checked the validity of area:

          QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index));
          qDebug() << area;
          ui->tabView->removeTab(index);
          qDebug() << area;
          

          QScrollArea(0x332d2b78)
          QScrollArea(0x332d2b78)

          @jsulm said:

          and if it is set parent to null to prevent it from being deleted if its parent is deleted.

          assigning a QWidget to a QLayout doesn't re-parent it?
          Anyway:

          qDebug() << area->parent();
          QVBoxLayout *layoutDialog = new QVBoxLayout();
          layoutDialog->addWidget(area);
          qDebug() << area->parent();
          dialog->setLayout(layoutDialog);
          

          QStackedWidget(0x333eda38, name = "qt_tabwidget_stackedwidget")
          QStackedWidget(0x333eda38, name = "qt_tabwidget_stackedwidget")

          So it seems not - I must remember it wrong.
          I did this:

          qDebug() << area->parent();
          QVBoxLayout *layoutDialog = new QVBoxLayout();
          layoutDialog->addWidget(area);
          area->setParent(dialog);
          qDebug() << area->parent();
          dialog->setLayout(layoutDialog);
          

          QStackedWidget(0x3330da38, name = "qt_tabwidget_stackedwidget")
          QDialog(0x34551b10)

          but still the dialog is empty.

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

          @Mark81 Just an idea: call show() after adding it to the layout

          layoutDialog->addWidget(area);
          area->show();
          // area->setParent(dialog); <-- remove this
          

          I didn't mean to call setParent() after adding to layout but before removing it from tabView.

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

          M 1 Reply Last reply
          2
          • jsulmJ jsulm

            @Mark81 Just an idea: call show() after adding it to the layout

            layoutDialog->addWidget(area);
            area->show();
            // area->setParent(dialog); <-- remove this
            

            I didn't mean to call setParent() after adding to layout but before removing it from tabView.

            M Offline
            M Offline
            Mark81
            wrote on last edited by
            #5

            @jsulm ok, the things begin to work:

            void MainWindow::tabView_tabCloseRequested(int index)
            {
                QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index));
                ui->tabView->removeTab(index);
            
                QDialog *dialog = new QDialog(this);
                dialog->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
            
                QLayout *layoutDialog = new QVBoxLayout();
                layoutDialog->addWidget(area);
                area->show();
                dialog->setLayout(layoutDialog);
            
                dialog->show();
            }
            

            the last (minor) issue is a warning about the geometry:

            setGeometry: Unable to set geometry 116x30+860+469 on QWidgetWindow/'QDialogClassWindow'. Resulting geometry: 116x92+860+469 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 92x92, maximum size: 16777215x16777215).

            The content is shown but it doesn't fit the initial size of the QDialog. Perhaps I have to manually set its size?

            jsulmJ 1 Reply Last reply
            0
            • M Mark81

              @jsulm ok, the things begin to work:

              void MainWindow::tabView_tabCloseRequested(int index)
              {
                  QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index));
                  ui->tabView->removeTab(index);
              
                  QDialog *dialog = new QDialog(this);
                  dialog->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
              
                  QLayout *layoutDialog = new QVBoxLayout();
                  layoutDialog->addWidget(area);
                  area->show();
                  dialog->setLayout(layoutDialog);
              
                  dialog->show();
              }
              

              the last (minor) issue is a warning about the geometry:

              setGeometry: Unable to set geometry 116x30+860+469 on QWidgetWindow/'QDialogClassWindow'. Resulting geometry: 116x92+860+469 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 92x92, maximum size: 16777215x16777215).

              The content is shown but it doesn't fit the initial size of the QDialog. Perhaps I have to manually set its size?

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

              @Mark81 said in Move QScrollArea between QWidgets:

              dialog->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);

              does it fit without this line?

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

              M 1 Reply Last reply
              0
              • jsulmJ jsulm

                @Mark81 said in Move QScrollArea between QWidgets:

                dialog->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);

                does it fit without this line?

                M Offline
                M Offline
                Mark81
                wrote on last edited by
                #7

                @jsulm no, the QDialog is very small. Of course I can set a size manually, but if I create such a dialog with the same items in Designer (instead of move widgets at run-time) the initial size is set according to the contents.

                jsulmJ 1 Reply Last reply
                0
                • M Mark81

                  @jsulm no, the QDialog is very small. Of course I can set a size manually, but if I create such a dialog with the same items in Designer (instead of move widgets at run-time) the initial size is set according to the contents.

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

                  @Mark81 You can try to call https://doc.qt.io/qt-5/qwidget.html#adjustSize on the dialog

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

                  M 1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @Mark81 You can try to call https://doc.qt.io/qt-5/qwidget.html#adjustSize on the dialog

                    M Offline
                    M Offline
                    Mark81
                    wrote on last edited by
                    #9

                    @jsulm with adjustSize() I don't receive anymore the warning about "Unable to set geometry" but still the size of the dialog is the same. Another trial I've done is to create a new QScrollArea and set its content, instead of move the whole QScrollArea from the other widget. Well, in this case the layout is shown correctly (i.e. the dialog's size fits the content) but I surely did it wrong because it add another "frame" or "widget" outside (you see it like a padding where it should not be).

                    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