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. Generating widgets dynamically
Forum Updated to NodeBB v4.3 + New Features

Generating widgets dynamically

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 972 Views
  • 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.
  • L Offline
    L Offline
    lukutis222
    wrote on last edited by lukutis222
    #1

    Hello. Up to this point I have been using widget.ui to generate widgets, assign slots to them. It was very convenient and easy to do but I have got to the point in my project where I need to create custom widgets programmatically based on user choice.

    In my QT application, there is a QComboBox that allows user to select from a few different options:

    c0519d30-453e-408d-b149-f1b65c553ad5-image.png

    When user selects one of the available options, a function in my program will be triggered:

    void Widget::on_Scenario_select_currentIndexChanged(int index)
    {
        qDebug("scenario selected =%s \n",ui->Scenario_select->currentText().toStdString().c_str());
    // if user selects Option1, generate QScrollArea and inside that area generate 4 Radio Buttons 
    
    // if user selects Option2, generate QScrollArea and inside that are generate 6 Radio Buttons.
    }
    

    For example, when user selects Option1, it I need to generate the following widgets:
    284a5593-54ef-467f-86c4-00a1284d4756-image.png
    5ab31130-fd16-4e46-a731-0e1af89a954a-image.png

    Could someone clarify to me how can this be done as I havent managed to find an easy example

    jsulmJ 1 Reply Last reply
    0
    • L lukutis222

      Hello. Up to this point I have been using widget.ui to generate widgets, assign slots to them. It was very convenient and easy to do but I have got to the point in my project where I need to create custom widgets programmatically based on user choice.

      In my QT application, there is a QComboBox that allows user to select from a few different options:

      c0519d30-453e-408d-b149-f1b65c553ad5-image.png

      When user selects one of the available options, a function in my program will be triggered:

      void Widget::on_Scenario_select_currentIndexChanged(int index)
      {
          qDebug("scenario selected =%s \n",ui->Scenario_select->currentText().toStdString().c_str());
      // if user selects Option1, generate QScrollArea and inside that area generate 4 Radio Buttons 
      
      // if user selects Option2, generate QScrollArea and inside that are generate 6 Radio Buttons.
      }
      

      For example, when user selects Option1, it I need to generate the following widgets:
      284a5593-54ef-467f-86c4-00a1284d4756-image.png
      5ab31130-fd16-4e46-a731-0e1af89a954a-image.png

      Could someone clarify to me how can this be done as I havent managed to find an easy example

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

      @lukutis222 Well, you could do all this in designer: use https://doc.qt.io/qt-6/qstackedwidget.html Using it you can create several "pages" with widgets and then simply show one of these pages based on user selection.

      Creating widgets dinamically is easy. To see how it is done you can take a look at auto-generated code (ui_xxx.h files). Also there are many examples in Qt documentation.

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

      L 1 Reply Last reply
      1
      • jsulmJ jsulm

        @lukutis222 Well, you could do all this in designer: use https://doc.qt.io/qt-6/qstackedwidget.html Using it you can create several "pages" with widgets and then simply show one of these pages based on user selection.

        Creating widgets dinamically is easy. To see how it is done you can take a look at auto-generated code (ui_xxx.h files). Also there are many examples in Qt documentation.

        L Offline
        L Offline
        lukutis222
        wrote on last edited by
        #3

        @jsulm
        Thanks for quick reply. The first option that you have suggested is not good idea for my particular example because there will be many different options available (I just show you example of 2 options) so I much rather generate ir programmatically.

        I have tried this so far:

        void Widget::on_Scenario_select_currentIndexChanged(int index)
        {
            qDebug("scenario selected =%s \n",ui->Scenario_select->currentText().toStdString().c_str());
             // if user selects Option1, generate
            if(ui->Scenario_select->currentText().toStdString()=="Option1"){
                qDebug("Option1 selected \n");
                QScrollArea scrollArea;
                scrollArea.setBackgroundRole(QPalette::Dark);
                scrollArea.show();
            }
        }
        

        The code above will create a scroll area and I can see it show up on my screen for a brief moment and then it dissapears immediately.

        Can you clarify where can I find the auto-generated code that you mentioned? In my project, I only see the following files:

        44a986e7-eabf-41dd-8aa8-333454afa3b9-image.png

        jsulmJ 1 Reply Last reply
        0
        • L lukutis222

          @jsulm
          Thanks for quick reply. The first option that you have suggested is not good idea for my particular example because there will be many different options available (I just show you example of 2 options) so I much rather generate ir programmatically.

          I have tried this so far:

          void Widget::on_Scenario_select_currentIndexChanged(int index)
          {
              qDebug("scenario selected =%s \n",ui->Scenario_select->currentText().toStdString().c_str());
               // if user selects Option1, generate
              if(ui->Scenario_select->currentText().toStdString()=="Option1"){
                  qDebug("Option1 selected \n");
                  QScrollArea scrollArea;
                  scrollArea.setBackgroundRole(QPalette::Dark);
                  scrollArea.show();
              }
          }
          

          The code above will create a scroll area and I can see it show up on my screen for a brief moment and then it dissapears immediately.

          Can you clarify where can I find the auto-generated code that you mentioned? In my project, I only see the following files:

          44a986e7-eabf-41dd-8aa8-333454afa3b9-image.png

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

          @lukutis222 said in Generating widgets dynamically:

          QScrollArea scrollArea;

          This can't work, because scrollArea is alocal variable which is destroyed as soon as on_Scenario_select_currentIndexChanged finishes. Create widgets on the heap, not stack.

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

          L 1 Reply Last reply
          1
          • jsulmJ jsulm

            @lukutis222 said in Generating widgets dynamically:

            QScrollArea scrollArea;

            This can't work, because scrollArea is alocal variable which is destroyed as soon as on_Scenario_select_currentIndexChanged finishes. Create widgets on the heap, not stack.

            L Offline
            L Offline
            lukutis222
            wrote on last edited by lukutis222
            #5

            @jsulm
            Thanks for clarifying.

            I have created testtool.cpp and testtool.h files where I want to keep all functions for creating custom widgets.

            testtool.h:

            #ifndef TESTTOOL_H
            #define TESTTOOL_H
            
            #include <QWidget>
            #include <QListView>
            #include <QScrollArea>
            #include <QRadioButton>
            
            class TestTool : public QWidget
            {
                Q_OBJECT
            public:
                explicit TestTool(QWidget *parent = nullptr);
                void Create_widgets();
            
            private:
            
                QScrollArea *scrollArea;
                QWidget *scrollAreaWidgetContents;
                QRadioButton *radioButton;
                QRadioButton *radioButton_2;
                QRadioButton *radioButton_3;
                QRadioButton *radioButton_4;
            
            signals:
            
            };
            
            #endif // TESTTOOL_H
            
            

            testtool.cpp

            #include "testtool.h"
            
            
            TestTool::TestTool(QWidget *parent)
                : QWidget{parent}
            {
            
            
            }
            
            void TestTool::Create_widgets(){
                scrollArea = new QScrollArea();
                scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
                scrollArea->setGeometry(QRect(30, 80, 481, 371));
                scrollArea->setWidgetResizable(true);
                scrollArea->show();
            }
            

            In my widget.cpp I create a class object for the testtool:

            Widget::Widget(QWidget *parent)
                : QWidget(parent)
                , ui(new Ui::Widget)
                , serial(new Serial)
                , file(new Logging)
                , test_tool_object(new TestTool)
            
            

            I use test_too_object to be able to call methods that are described in the testtool.

            As you can see I have only one method in testtool:

            void TestTool::Create_widgets(){
                scrollArea = new QScrollArea();
                scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
                scrollArea->setGeometry(QRect(30, 80, 481, 371));
                scrollArea->setWidgetResizable(true);
                scrollArea->show();
            }
            
            

            And I call this method when the scenario option is selected:

            void Widget::on_Scenario_select_currentIndexChanged(int index)
            {
                qDebug("scenario selected =%s \n",ui->Scenario_select->currentText().toStdString().c_str());
                 // if user selects Option1, generate
                if(ui->Scenario_select->currentText().toStdString()=="Option1"){
                    qDebug("Option1 selected \n");
                    //Create_widgets
                    test_tool_object->Create_widgets();
            
                }
            
            
            
            }
            

            However, when I selection "Option1" the qscrollarea is create but it is not linked with my main widget. Is that because I have not set it to be a child for my main widget?

            6a39fb33-fb7c-42f1-8fea-de4459a5bc0d-image.png

            jsulmJ 1 Reply Last reply
            0
            • L lukutis222

              @jsulm
              Thanks for clarifying.

              I have created testtool.cpp and testtool.h files where I want to keep all functions for creating custom widgets.

              testtool.h:

              #ifndef TESTTOOL_H
              #define TESTTOOL_H
              
              #include <QWidget>
              #include <QListView>
              #include <QScrollArea>
              #include <QRadioButton>
              
              class TestTool : public QWidget
              {
                  Q_OBJECT
              public:
                  explicit TestTool(QWidget *parent = nullptr);
                  void Create_widgets();
              
              private:
              
                  QScrollArea *scrollArea;
                  QWidget *scrollAreaWidgetContents;
                  QRadioButton *radioButton;
                  QRadioButton *radioButton_2;
                  QRadioButton *radioButton_3;
                  QRadioButton *radioButton_4;
              
              signals:
              
              };
              
              #endif // TESTTOOL_H
              
              

              testtool.cpp

              #include "testtool.h"
              
              
              TestTool::TestTool(QWidget *parent)
                  : QWidget{parent}
              {
              
              
              }
              
              void TestTool::Create_widgets(){
                  scrollArea = new QScrollArea();
                  scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
                  scrollArea->setGeometry(QRect(30, 80, 481, 371));
                  scrollArea->setWidgetResizable(true);
                  scrollArea->show();
              }
              

              In my widget.cpp I create a class object for the testtool:

              Widget::Widget(QWidget *parent)
                  : QWidget(parent)
                  , ui(new Ui::Widget)
                  , serial(new Serial)
                  , file(new Logging)
                  , test_tool_object(new TestTool)
              
              

              I use test_too_object to be able to call methods that are described in the testtool.

              As you can see I have only one method in testtool:

              void TestTool::Create_widgets(){
                  scrollArea = new QScrollArea();
                  scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
                  scrollArea->setGeometry(QRect(30, 80, 481, 371));
                  scrollArea->setWidgetResizable(true);
                  scrollArea->show();
              }
              
              

              And I call this method when the scenario option is selected:

              void Widget::on_Scenario_select_currentIndexChanged(int index)
              {
                  qDebug("scenario selected =%s \n",ui->Scenario_select->currentText().toStdString().c_str());
                   // if user selects Option1, generate
                  if(ui->Scenario_select->currentText().toStdString()=="Option1"){
                      qDebug("Option1 selected \n");
                      //Create_widgets
                      test_tool_object->Create_widgets();
              
                  }
              
              
              
              }
              

              However, when I selection "Option1" the qscrollarea is create but it is not linked with my main widget. Is that because I have not set it to be a child for my main widget?

              6a39fb33-fb7c-42f1-8fea-de4459a5bc0d-image.png

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

              @lukutis222 said in Generating widgets dynamically:

              Is that because I have not set it to be a child for my main widget?

              yes

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

              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