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. Combining classes - append class to QMainWindow

Combining classes - append class to QMainWindow

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

    My objective is to
    develop QWidget class - using GUI - QtDesigner.
    ( My current example is QMdiArea )
    then add / include / import / append (choose your terminology) this QWidget to QMainWindow class USING CODE .

    Here is my basic code

        MdiArea *mdiarea = new MdiArea();
        layout()->addWidget(mdiarea);
        mdiarea->show();
    
    
    

    It has an issue , I am getting this runtime error

    QMainWindowLayout::addItem: Please use the public QMainWindow API instead
    

    add the result display writes over QMainWindow bars

    e4ffb48b-460f-4e97-b3a8-2c311fd536e1-image.png

    1. How do I verify the actual QMainWindow UI setup AFTER this code ?
    2. It appears the my code is adding / replacing "centralwidget" with QMdiArea - that is NOT my goal.

    So - how do I add QMdiArea to "cenralwidget"?

    Chris KawaC 1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #37

      Keep your cool everyone. The world is messed up as it is. Lets try to stay positive and friendly at least here ;)

      Anywho...

      why does intelisense offers inaccessible pointer as a valid entry ?

      It's a best guess effort. C++ is complicated language to provide accurate suggestions without actually compiling the whole thing. In some cases it doesn't have enough context so it uses heuristics to merely suggest what a valid syntax for given expression is without much consideration for the actual correctness of the program as a whole. Code completion is usually a lot more accurate in managed languages like C# or Java, as you have full language reflection at your disposal. In C++ a simple thing like #define true false can wreak havoc on suggestions.

      I'd suggest to treat code completion as a basic name and syntax helper. Sometimes you don't remember exact function or parameter name. Sometimes the param list is just long and it helps you save a few key strokes to type it in. Sometimes you want to quickly browse through class members looking for familiar keyword. For those cases it works well enough. I wouldn't rely on it to suggest meaningful code logic though. That should be on the programmer anyway IMO. In case of connect's it's especially important to understand what relations you're creating so relying on machine suggestions is not a good idea, at least until we have that world class AI made :P

      1 Reply Last reply
      2
      • A Anonymous_Banned275

        My objective is to
        develop QWidget class - using GUI - QtDesigner.
        ( My current example is QMdiArea )
        then add / include / import / append (choose your terminology) this QWidget to QMainWindow class USING CODE .

        Here is my basic code

            MdiArea *mdiarea = new MdiArea();
            layout()->addWidget(mdiarea);
            mdiarea->show();
        
        
        

        It has an issue , I am getting this runtime error

        QMainWindowLayout::addItem: Please use the public QMainWindow API instead
        

        add the result display writes over QMainWindow bars

        e4ffb48b-460f-4e97-b3a8-2c311fd536e1-image.png

        1. How do I verify the actual QMainWindow UI setup AFTER this code ?
        2. It appears the my code is adding / replacing "centralwidget" with QMdiArea - that is NOT my goal.

        So - how do I add QMdiArea to "cenralwidget"?

        Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by Chris Kawa
        #2

        @AnneRanch Sounds like you actually want to set the MdiArea as the central widget. In that case

        setCentralWidget(mdiarea);
        

        If, on the other hand, you indeed already have a central widget and you want to add that mdiArea to it then

        centralWidget()->layout()->addWidget(mdiarea);
        

        assuming of course that this central widget has a layout. If not then you need to create one.

        1 Reply Last reply
        4
        • A Offline
          A Offline
          Anonymous_Banned275
          wrote on last edited by
          #3

          @Chris-Kawa said in Combining classes - append class to QMainWindow:

          centralWidget()->layout()->addWidget(mdiarea);

          Hello Chris,
          no go , I missed something.

          Yes, I like to add to centralWidget.

          91caaa96-9979-4ebf-867d-9f348011feba-image.png

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #4

            QMainWidnow doesn't have any central widget by default, so do you actually have a central widget? i.e. does centralWidget() return a non-nullptr ?
            From the picture I see you don't have one added in code so have you added it in the designer?
            If so - does it have a layout? i.e. does centralWidget()->layout() return a non-nullptr?

            1 Reply Last reply
            1
            • A Offline
              A Offline
              Anonymous_Banned275
              wrote on last edited by
              #5

              Yes, I did build QMainWindow using QtDesigner GUI and it does have centralWidget. I'll try to just replace it with the QMdiArea.
              I did some more reading on QMainWindow and it looks as I COULD replace default centralWidegt with QDock and then add centralWidget "inside" QDock.
              It is getting too complicated , but it may be the best final solution.

              Chris KawaC 1 Reply Last reply
              0
              • A Anonymous_Banned275

                Yes, I did build QMainWindow using QtDesigner GUI and it does have centralWidget. I'll try to just replace it with the QMdiArea.
                I did some more reading on QMainWindow and it looks as I COULD replace default centralWidegt with QDock and then add centralWidget "inside" QDock.
                It is getting too complicated , but it may be the best final solution.

                Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @AnneRanch That doesn't sound right.
                QMainWindow has an internal layout implementation and has an API that allows you to add one widget as a central widget, a widget as a toolbar, menubar and a bunch of QDockWidgets. Sorry to question you, but it really look s like you just don't have a central widget. It sounds like you want your mdi area to be the central widget so just setCentralWidget(mdiarea). If that's really really not the case could you post a screenshot of your widget hierarchy in the designer?

                1 Reply Last reply
                3
                • A Offline
                  A Offline
                  Anonymous_Banned275
                  wrote on last edited by Anonymous_Banned275
                  #7

                  I did replace the default centerWidget and it works "BETTER".
                  Now I have status bar , but Mdi still writes over menubar

                     MdiArea *mdiarea = new MdiArea();
                      if(centralWidget())
                          std::cout <<"TOK centralWidget()  " <<std::endl;
                      else
                           std::cout <<"FAILED centralWidget()  " <<std::endl;
                       setCentralWidget(mdiarea);
                  

                  f72f277c-dd9e-473e-b767-2d02266457e0-image.png

                  JonBJ 1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #8

                    Ok, you do have a central widget in designer but it doesn't have a layout (the red crossed circle indicates that), so centralWidget()->layout() is null. That's why it crashed.

                    Couple of options:

                    1. (That's the one I'd recommend) Delete the central widget in designer and set mdiarea to be it from code:
                    setCentralWidget(mdiarea);
                    
                    1. Add a layout to your central widget in designer and then you can do
                    centralWidget()->layout()->addWidget(mdiarea);
                    
                    1. Add the layout from code and add a widget to it:
                    QVBoxLayout* central_widget_layout = new QVBoxLayout(centralWidget());
                    central_widget_layout->addWidget(mdiarea);
                    

                    but Mdi still writes over menubar

                    I don't think it does. You just don't have anything in the menubar so it doesn't show up. It will show up once you add some menus or actions to it.

                    1 Reply Last reply
                    3
                    • A Offline
                      A Offline
                      Anonymous_Banned275
                      wrote on last edited by
                      #9

                      Thanks.
                      You solved THREE "problems" in one post !
                      I did not realize default QMainWindow form does not have a layout.
                      I did not actually know what is "THE LAYOUT" and how it fits into the scheme of things.
                      And I'll add some stuff to menu bar to see it .

                      Great progress, but I need to fine tune it by adding the "rotten" btscanner dialogue as QDock next...

                      SGaistS 1 Reply Last reply
                      0
                      • A Anonymous_Banned275

                        Thanks.
                        You solved THREE "problems" in one post !
                        I did not realize default QMainWindow form does not have a layout.
                        I did not actually know what is "THE LAYOUT" and how it fits into the scheme of things.
                        And I'll add some stuff to menu bar to see it .

                        Great progress, but I need to fine tune it by adding the "rotten" btscanner dialogue as QDock next...

                        SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #10

                        Hi,

                        @AnneRanch said in Combining classes - append class to QMainWindow:

                        I did not realize default QMainWindow form does not have a layout.

                        In fact it does have one and that's why you got the error message when trying to use it. QMainWindow's layout is "protected" because it's it that provides support for dock widgets toolbars etc.

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

                          @Chris-Kawa said in Combining classes - append class to QMainWindow:

                          but it doesn't have a layout (the red crossed circle indicates that)

                          OK, clarification needed.

                          Even AFTER adding "form layout" I still have "red crossed circle" showing in the icon. No errors.

                          Having presence or being "protected" seems to be TWO different properties.

                          So which one "is causing the problem" encountered?

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            Anonymous_Banned275
                            wrote on last edited by
                            #12

                            Expanding on the original post.
                            Adding tab class to MainWindow by setting new centralwidget bypasses the missing / private "layout" . That works as desired.

                            After that, similar process needs to be done "dowstream" - add QDialog to Tab class. Here the QDialoig does not have "centralwidget" to be replaced.
                            So it is back to "layout" which does not exists or is private.

                            Or I can go back to original - replacing QDialog with QWidget.
                            Prefer no to do so - woudl have to convert more QDialogs to QWidgets.

                            Any different solution , similar to centrawidget / layout , would be appreciated.

                            JKSHJ 1 Reply Last reply
                            0
                            • A Anonymous_Banned275

                              Expanding on the original post.
                              Adding tab class to MainWindow by setting new centralwidget bypasses the missing / private "layout" . That works as desired.

                              After that, similar process needs to be done "dowstream" - add QDialog to Tab class. Here the QDialoig does not have "centralwidget" to be replaced.
                              So it is back to "layout" which does not exists or is private.

                              Or I can go back to original - replacing QDialog with QWidget.
                              Prefer no to do so - woudl have to convert more QDialogs to QWidgets.

                              Any different solution , similar to centrawidget / layout , would be appreciated.

                              JKSHJ Offline
                              JKSHJ Offline
                              JKSH
                              Moderators
                              wrote on last edited by
                              #13

                              @AnneRanch said in Combining classes - append class to QMainWindow:

                              Here the QDialoig does not have "centralwidget" to be replaced.

                              It doesn't indeed. QMainWindow is a special widget with many regions including the "central" region. No other widgets have this structure. See the documentation at https://doc.qt.io/qt-5/qmainwindow.html :

                              QMainWindow layout

                              So it is back to "layout" which does not exists or is private.

                              ...

                              Any different solution , similar to centrawidget / layout , would be appreciated.

                              Just like you call setCentralWidget() on QMainWindow, you can call setLayout() on plain "container" widgets like QWidget, QDialog, and QGroupBox.

                              add QDialog to Tab class

                              Can you explain your rationale for doing this?

                              A dialog is designed to be a separate pop-up window. A tab widget is for "embedding" other widget inside an existing window. They have opposite goals.

                              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                              1 Reply Last reply
                              4
                              • A Anonymous_Banned275

                                I did replace the default centerWidget and it works "BETTER".
                                Now I have status bar , but Mdi still writes over menubar

                                   MdiArea *mdiarea = new MdiArea();
                                    if(centralWidget())
                                        std::cout <<"TOK centralWidget()  " <<std::endl;
                                    else
                                         std::cout <<"FAILED centralWidget()  " <<std::endl;
                                     setCentralWidget(mdiarea);
                                

                                f72f277c-dd9e-473e-b767-2d02266457e0-image.png

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

                                @AnneRanch
                                Going back for a moment to your earlier screenshot, and something @Chris-Kawa said about it. When using Qt Designer and you look at that "Object/Class" window showing your widget hierarchy: anywhere there you might see any widget you have added showing that "red-crossed-circle no-entry sign" on the widget. That indicates you should right click on that widget and add a layout to it. Without that, your widget layout is liable to be wrong.

                                A 1 Reply Last reply
                                2
                                • A Offline
                                  A Offline
                                  Anonymous_Banned275
                                  wrote on last edited by Anonymous_Banned275
                                  #15

                                  Well , not sure if the group wants to continue this discussion.
                                  Been chastised for "reinventing wheel ", using stuff DIFFERENTLY than usual etc, Really do not want to repeat that, so let me leave WHY I am doing this alone. Maybe later...

                                  I prefer KISS, so my initial approach was to use QtCreator and build , using QtDesigner , base QMainWindow class.
                                  I did try QtCreator examples "Application" but it does not use Ui and I was not comfortable modifying "Application" example to fit my goal.

                                  However, the QMainWindow class build GUI "form" does not indicate , with the exception (red cross ) I just learn during this discussion, that "layout" is mandatory.

                                  That is still unresolved , because AFTER I manually add , using QtDesigner, " form layout " - the "red cross" is still there.

                                  As far as using code to reset "centralwidget" I am questioning the necessity of having "layout" - the application GUI works with no specific layout, just "free hand" , which to me makes sense.
                                  ( Not sure of advantage of using "form layout" during development - machine second-guessing the location of widgets or vice versa)

                                  BUT it looks as adding new QWidget to QMainWindow WITHOUT having "layout" is an issue.
                                  ( this format is awkward - I cannot see the previous post to intelligently reply to it )

                                  Now back to adding QDialog.
                                  I did try to add "layout" using code , but could not find how to code it . I got as far as QLayoutItem. I am still learning to navigate QtCreator.

                                   ui->tab->setLayout(????); // test add layout to first tab 
                                  

                                  PS
                                  Here is another, unconventional approach , to similar task
                                  https://stackoverflow.com/questions/23676283/splitting-qt-forms-between-multiple-ui-files
                                  Just to point out I am not the only crazy one.

                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @AnneRanch
                                    Going back for a moment to your earlier screenshot, and something @Chris-Kawa said about it. When using Qt Designer and you look at that "Object/Class" window showing your widget hierarchy: anywhere there you might see any widget you have added showing that "red-crossed-circle no-entry sign" on the widget. That indicates you should right click on that widget and add a layout to it. Without that, your widget layout is liable to be wrong.

                                    A Offline
                                    A Offline
                                    Anonymous_Banned275
                                    wrote on last edited by
                                    #16

                                    @JonB
                                    Do I understand it correctly - adding "layout" to "centralwidget" is not enough to remove the "red cross" ?
                                    "layout" needs to be added to any widget "bellow" the "centralwidget".

                                    That is pretty minor issue - still looking for an answer why "layout" needs to be used at all when adding widgets in code.

                                    Pl45m4P 1 Reply Last reply
                                    0
                                    • Chris KawaC Offline
                                      Chris KawaC Offline
                                      Chris Kawa
                                      Lifetime Qt Champion
                                      wrote on last edited by Chris Kawa
                                      #17

                                      Layouts are sort of a geometry managers for child widgets. When you resize a widget its layout takes care of moving and resizing the children to accommodate new parent size.

                                      A widget has either no layout or exactly one. This is indicated via that icon we talked about. If a widget has no layout its children sizes and positions are not automatically adjusted and can overlap. In such case you are responsible for manually calling setPos, move, resize, setGeometry or any other similar functions to set a correct child geometry. Layouts are a way of automating this tedious task. If a widget has a layout set it will react to the widgets resizeEvent and adjust children according to the layout's type. For example a QVBoxLayout will place children one under the other. QGridLayout will place them in a grid etc.

                                      Now for a little confusing part. You said you added a layout and it didn't remove the red circle. If you did that by dragging a layout from the toolbox on the left like you would with a button or a frame then you didn't set a layout on the widget. You added a new widget with that layout set, so what you have is the original widget, still without layout and a child with that layout.

                                      The option to set a layout on a widget is either in the right click menu under the "Lay out" sub-menu or on the toolbar (icons with dots, horizontal and vertical bars). An important note is that designer does not allow to set a layout on a widget that has no children (because it's usually not what you want anyway) so if you don't have any children those options will be grayed out.

                                      If you want to do that anyway you can workaround it with these steps:

                                      • add any child widget to the widget you want the layout set on (button, frame or whatever)
                                      • select the widget you want the layout to be set on
                                      • use either the right clik menu or the toolbar icons to set a layout (vertical, horizontal or grid)
                                      • remove the child widget you added previously

                                      This is not something you usually do though. Usually you either add children and set layout in the designer or do both of those from code.

                                      1 Reply Last reply
                                      4
                                      • A Anonymous_Banned275

                                        @JonB
                                        Do I understand it correctly - adding "layout" to "centralwidget" is not enough to remove the "red cross" ?
                                        "layout" needs to be added to any widget "bellow" the "centralwidget".

                                        That is pretty minor issue - still looking for an answer why "layout" needs to be used at all when adding widgets in code.

                                        Pl45m4P Offline
                                        Pl45m4P Offline
                                        Pl45m4
                                        wrote on last edited by Pl45m4
                                        #18

                                        @AnneRanch said in Combining classes - append class to QMainWindow:

                                        is not enough to remove the "red cross"

                                        It is, but if you do this in code, you will still see the red cross in QtDesigner, because your coded layout applies at run-time.

                                        Every widget or widget container can / should have a layout. Otherwise its content is floating around and it will produce other unwanted behavior, in terms of size (resizing) and position (while moving).

                                        So every new QMainWindow has its centralWidget, which is empty and has no layout set, per default. You could either add content to it, by drag'n'drop, using QtDesigner and then right click centralWidget -> Layout -> Then pick layout of your choice or you set a layout by using your code, then "grab" that layout again and add widgets (content)

                                        QHBoxLayout *cW_Layout = new QHBoxLayout;
                                        this->centralWidget->setLayout(cW_Layout);
                                        
                                        // To access your CW or its layout, do
                                        centralWidget->layout()->addWidget(  WIDGET_TO_ADD );
                                        
                                        // Ofc you can also populate your layout first before adding it to centralWidget
                                        

                                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                        ~E. W. Dijkstra

                                        A 1 Reply Last reply
                                        0
                                        • A Offline
                                          A Offline
                                          Anonymous_Banned275
                                          wrote on last edited by
                                          #19

                                          I need to restate - I did change / add layout in QtDesigner to observe the red cross persistence.

                                          I did not do that in code.

                                          As far as layout "automatically " do resizing - I am still in basic app development , hence I am happy camper when I see expected "static" results , I am not in position to move / resize things around at this stage.
                                          However, it is nice to know WHY to use layout in future, even it is not of my primary concerns for now.

                                          Cheers

                                          1 Reply Last reply
                                          0
                                          • Pl45m4P Pl45m4

                                            @AnneRanch said in Combining classes - append class to QMainWindow:

                                            is not enough to remove the "red cross"

                                            It is, but if you do this in code, you will still see the red cross in QtDesigner, because your coded layout applies at run-time.

                                            Every widget or widget container can / should have a layout. Otherwise its content is floating around and it will produce other unwanted behavior, in terms of size (resizing) and position (while moving).

                                            So every new QMainWindow has its centralWidget, which is empty and has no layout set, per default. You could either add content to it, by drag'n'drop, using QtDesigner and then right click centralWidget -> Layout -> Then pick layout of your choice or you set a layout by using your code, then "grab" that layout again and add widgets (content)

                                            QHBoxLayout *cW_Layout = new QHBoxLayout;
                                            this->centralWidget->setLayout(cW_Layout);
                                            
                                            // To access your CW or its layout, do
                                            centralWidget->layout()->addWidget(  WIDGET_TO_ADD );
                                            
                                            // Ofc you can also populate your layout first before adding it to centralWidget
                                            
                                            A Offline
                                            A Offline
                                            Anonymous_Banned275
                                            wrote on last edited by
                                            #20

                                            @Pl45m4 said in Combining classes - append class to QMainWindow:

                                            @AnneRanch said in Combining classes - append class to QMainWindow:

                                            is not enough to remove the "red cross"

                                            It is, but if you do this in code, you will still see the red cross in QtDesigner, because your coded layout applies at run-time.

                                            Every widget or widget container can / should have a layout. Otherwise its content is floating around and it will produce other unwanted behavior, in terms of size (resizing) and position (while moving).

                                            So every new QMainWindow has its centralWidget, which is empty and has no layout set, per default. You could either add content to it, by drag'n'drop, using QtDesigner and then right click centralWidget -> Layout -> Then pick layout of your choice or you set a layout by using your code, then "grab" that layout again and add widgets (content)

                                            QHBoxLayout *cW_Layout = new QHBoxLayout;
                                            this->centralWidget->setLayout(cW_Layout);
                                            
                                            // To access your CW or its layout, do
                                            centralWidget->layout()->addWidget(  WIDGET_TO_ADD );
                                            
                                            // Ofc you can also populate your layout first before adding it to centralWidget
                                            

                                            This post is pretty much repeat of what was already said.
                                            This is not criticism, just a statement of fact.

                                            While applying similar approach in "layout-less" QDialog , as fas as QMianWindow" sees it, I have opted to use "promotion" and it works as desired.

                                            Of course the "promoted" form has "layout" already.
                                            I hope that makes sense.

                                            Pl45m4P 1 Reply Last reply
                                            -1

                                            • Login

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