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. nullptr layout from widget inside QTabWidget?
Forum Updated to NodeBB v4.3 + New Features

nullptr layout from widget inside QTabWidget?

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

    I'm trying to get a child of a widget within a layout from QTabWidget

    It's inserted like this:

    QWidget* containerWidget = new QWidget();
    containerWidget->setLayout(new QVBoxLayout());
    containerWidget->layout()->addWidget(new ViewWidget());
    tabWidget->insertTab(index, containerWidget, "Example");
    tabWidget->setCurrentIndex(index);
    

    Then I try to reacquire it with:

    QWidget* containerWidget = tabWidget->widget(index);
    ViewWidget* viewWidget = qobject_cast<ViewWidget*>(containerWidget->layout()->itemAt(0)->widget());
    

    But layout returns nullptr? What am I doing wrong?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Andaharoo
      wrote on last edited by
      #7

      @SGaist As I said earlier it is created within the markup (.ui file). It is a QWidget promoted into my ViewWidget. In my MainWindow the "ui_MainWindow.h" is included and Ui::MainWindowWidget ui; is declared as a member and setup. ui.viewWidget1 is ultimately where it exists. However, over the course of the program the tabs and contained ViewWidget's will be added and removed. Thus I cannot access it this way for all tabs. For example, the ui.viewWidget1 could be deleted when the tab is deleted.

      Looking at the file generated by Qt it did:

              tabWidget1 = new QTabWidget(centralwidget);
              tabWidget1->setObjectName(QString::fromUtf8("tabWidget1"));
              tabWidget1->setTabsClosable(false);
              tabWidget1->setMovable(true);
              tab1 = new QWidget();
              tab1->setObjectName(QString::fromUtf8("tab1"));
              verticalLayout = new QVBoxLayout(tab1);
              verticalLayout->setSpacing(0);
              verticalLayout->setContentsMargins(11, 11, 11, 11);
              verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
              verticalLayout->setContentsMargins(0, 0, 0, 0);
              viewWidget1 = new View3DWidget(tab1);
              viewWidget1->setObjectName(QString::fromUtf8("viewWidget1"));
      
              verticalLayout->addWidget(viewWidget1);
      

      The layout was not set to the widget with setLayout but the widget was given through the constructor to the layout. So this brings me to the question. What's the difference between doing:

      QWidget* parent = new QWidget();
      QVBoxLayout* layout= new QVBoxLayout(parent);
      

      and

      QWidget* parent = new QWidget();
      QVBoxLayout* layout = new QVBoxlayout();
      parent->setLayout(layout);
      

      In fact, if I manually edit Qt's generated code to be the latter, my code then works and I can use:

      ViewWidget* viewWidget = qobject_cast<ViewWidget*>(tabWidget->widget(index)->layout()->itemAt(0)->widget());
      

      to obtain whatever view is present.

      So I then just solved this by removing the initial tabs from QTabWidget in the markup and adding them myself as shown above. This solved the problem and seems like a more appropriate solution as it prevents some nullptrs hanging around in the generated Ui::MainWindowWidget for tabs that were deleted.

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

        Hi,

        This looks pretty convoluted. Why not have your ViewWidget be responsible for returning its internal widget ?

        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
        • A Offline
          A Offline
          Andaharoo
          wrote on last edited by
          #3

          Yeah that's the first thing I tried but it didn't work. I'm using .ui file for the initialization of the tabwidget and Qt Creator doesn't let you set a layout on the tab widget directly. So you have to do:

          QTabWidget
            BaseWidget
              Layout
                Widget I want to fill the tab widget
          

          What you're suggesting sounds like

          QTabWidget
            Layout
              MyWidget
          

          0_1550105183087_2019-02-13 18_45_04-MainWindow.ui [Temp] - Qt Creator.jpg
          Maybe I just don't know how to do it in Qt Creator?

          jsulmJ 1 Reply Last reply
          0
          • A Andaharoo

            Yeah that's the first thing I tried but it didn't work. I'm using .ui file for the initialization of the tabwidget and Qt Creator doesn't let you set a layout on the tab widget directly. So you have to do:

            QTabWidget
              BaseWidget
                Layout
                  Widget I want to fill the tab widget
            

            What you're suggesting sounds like

            QTabWidget
              Layout
                MyWidget
            

            0_1550105183087_2019-02-13 18_45_04-MainWindow.ui [Temp] - Qt Creator.jpg
            Maybe I just don't know how to do it in Qt Creator?

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

            @Andaharoo I think what @SGaist means is that your ViewWidget has a method which returns the internal widget, so the the caller does not have to know any internal details of ViewWidget.

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

            A 1 Reply Last reply
            0
            • jsulmJ jsulm

              @Andaharoo I think what @SGaist means is that your ViewWidget has a method which returns the internal widget, so the the caller does not have to know any internal details of ViewWidget.

              A Offline
              A Offline
              Andaharoo
              wrote on last edited by
              #5

              @jsulm @SGaist I think I read that wrong or it was edited. What does he mean by "Internal Widget" the only thing inside ViewWidget is a QVTK widget from VTK to display 3d views and the such through Qt.

              Or do you mean get the parent through the ViewWidget? I don't have the ViewWidget and I'm trying to get it. All I have is the tab widget and need to acquire the ViewWidget which is inside the TabWidget. But the normal way I would access children from a layout is not working.

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

                Where does that ViewWidget come from then ?

                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
                • A Offline
                  A Offline
                  Andaharoo
                  wrote on last edited by
                  #7

                  @SGaist As I said earlier it is created within the markup (.ui file). It is a QWidget promoted into my ViewWidget. In my MainWindow the "ui_MainWindow.h" is included and Ui::MainWindowWidget ui; is declared as a member and setup. ui.viewWidget1 is ultimately where it exists. However, over the course of the program the tabs and contained ViewWidget's will be added and removed. Thus I cannot access it this way for all tabs. For example, the ui.viewWidget1 could be deleted when the tab is deleted.

                  Looking at the file generated by Qt it did:

                          tabWidget1 = new QTabWidget(centralwidget);
                          tabWidget1->setObjectName(QString::fromUtf8("tabWidget1"));
                          tabWidget1->setTabsClosable(false);
                          tabWidget1->setMovable(true);
                          tab1 = new QWidget();
                          tab1->setObjectName(QString::fromUtf8("tab1"));
                          verticalLayout = new QVBoxLayout(tab1);
                          verticalLayout->setSpacing(0);
                          verticalLayout->setContentsMargins(11, 11, 11, 11);
                          verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
                          verticalLayout->setContentsMargins(0, 0, 0, 0);
                          viewWidget1 = new View3DWidget(tab1);
                          viewWidget1->setObjectName(QString::fromUtf8("viewWidget1"));
                  
                          verticalLayout->addWidget(viewWidget1);
                  

                  The layout was not set to the widget with setLayout but the widget was given through the constructor to the layout. So this brings me to the question. What's the difference between doing:

                  QWidget* parent = new QWidget();
                  QVBoxLayout* layout= new QVBoxLayout(parent);
                  

                  and

                  QWidget* parent = new QWidget();
                  QVBoxLayout* layout = new QVBoxlayout();
                  parent->setLayout(layout);
                  

                  In fact, if I manually edit Qt's generated code to be the latter, my code then works and I can use:

                  ViewWidget* viewWidget = qobject_cast<ViewWidget*>(tabWidget->widget(index)->layout()->itemAt(0)->widget());
                  

                  to obtain whatever view is present.

                  So I then just solved this by removing the initial tabs from QTabWidget in the markup and adding them myself as shown above. This solved the problem and seems like a more appropriate solution as it prevents some nullptrs hanging around in the generated Ui::MainWindowWidget for tabs that were deleted.

                  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