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. Getting QMainWindow to fit its central widget
Forum Updated to NodeBB v4.3 + New Features

Getting QMainWindow to fit its central widget

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 3 Posters 10.0k Views 3 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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by mrjj
    #4

    but its still not clear to me why you cannot let the widget follow mainwindow
    and then just set mainwindow to size that allow the size of the widget you want?
    If u set
    ui->IMSELFPAINTED->setMinimumSize(800,600);
    i get green area of that size. and mainwindow somewhat bigger.
    You cannot do like that?

    then later, maybe in showevent, call
    ui->IMSELFPAINTED->setMinimumSize(0,0);
    to allow any resize.

    H 1 Reply Last reply
    1
    • mrjjM mrjj

      but its still not clear to me why you cannot let the widget follow mainwindow
      and then just set mainwindow to size that allow the size of the widget you want?
      If u set
      ui->IMSELFPAINTED->setMinimumSize(800,600);
      i get green area of that size. and mainwindow somewhat bigger.
      You cannot do like that?

      then later, maybe in showevent, call
      ui->IMSELFPAINTED->setMinimumSize(0,0);
      to allow any resize.

      H Offline
      H Offline
      Harry123
      wrote on last edited by Harry123
      #5

      @mrjj

      I currently do use setMinimumSize as a stop-gap measure while developing.

      The setMinimumSize(0,0) solution is certainly much simpler than all my monkeying with size policies.

      Question: Is showEvent for the central widget safe enough, I mean is it done after all size adjustments were already set (at least until some future resize) ?

      mrjjM 1 Reply Last reply
      0
      • H Harry123

        @mrjj

        I currently do use setMinimumSize as a stop-gap measure while developing.

        The setMinimumSize(0,0) solution is certainly much simpler than all my monkeying with size policies.

        Question: Is showEvent for the central widget safe enough, I mean is it done after all size adjustments were already set (at least until some future resize) ?

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #6

        @Harry123
        well it would be showEvent for mainwindow.
        Normally its safe yes. All sizes set and layouts resolved.

        H 1 Reply Last reply
        1
        • mrjjM mrjj

          @Harry123
          well it would be showEvent for mainwindow.
          Normally its safe yes. All sizes set and layouts resolved.

          H Offline
          H Offline
          Harry123
          wrote on last edited by
          #7

          @mrjj

          Many thanks for the idea - I will be trying that later and will report if problems.

          mrjjM 1 Reply Last reply
          0
          • H Harry123

            @mrjj

            Many thanks for the idea - I will be trying that later and will report if problems.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #8

            @Harry123
            Good luck.
            Note.
            I just added layout to mainwindow and then a widget. ( the green one)
            So its not directly on centralwidget.

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

              You don't need all this toying around. The default size policy is QSizePolicy::Preferred, which means it uses size hint of the widget when it is shown.

              As for the menu bar - the easiest way is add it to the layout. You don't have to use that layout for any other children. It can be there just for the menu bar and you can place other children manually. Here's a demo:

              #include <QApplication>
              #include <QPushButton>
              #include <QMenuBar>
              #include <QVBoxLayout>
              
              struct Foo : public QWidget {
                  QSize sizeHint() const override { return QSize(400,400); }
              };
              
              int main(int argc, char *argv[]) {
                  QApplication a(argc, argv);
              
                  Foo foo;
                  foo.setLayout(new QVBoxLayout()); //use a layout for menu bar
                  foo.layout()->setMenuBar(new QMenuBar());
                  foo.layout()->menuBar()->addAction(new QAction("Hi!", &foo));
              
                  QPushButton* p = new QPushButton(&foo); //don't use layout, place it manually
                  p->move(100,100);
              
                  foo.show();
              
                  return a.exec();
              }
              

              If you really don't want the layout for some reason here's the version with main window wrapper, but it's not really necessary:

              #include <QApplication>
              #include <QPushButton>
              #include <QMenuBar>
              
              struct Foo : public QWidget {
                  QSize sizeHint() const override { return QSize(400,400); }
              };
              
              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
              
                  QMainWindow w;
                  w.setMenuBar(new QMenuBar()); //use the built-in layout for menu bar
                  w.menuBar()->addAction("Hi!");
                  w.setCentralWidget(new Foo); //place the widget in built-in layout
              
                  QPushButton* p = new QPushButton(w.centralWidget());  //place the child manually
                  p->move(100,100);
              
                  w.show();
              
                  return a.exec();
              }
              
              H 1 Reply Last reply
              1
              • Chris KawaC Chris Kawa

                You don't need all this toying around. The default size policy is QSizePolicy::Preferred, which means it uses size hint of the widget when it is shown.

                As for the menu bar - the easiest way is add it to the layout. You don't have to use that layout for any other children. It can be there just for the menu bar and you can place other children manually. Here's a demo:

                #include <QApplication>
                #include <QPushButton>
                #include <QMenuBar>
                #include <QVBoxLayout>
                
                struct Foo : public QWidget {
                    QSize sizeHint() const override { return QSize(400,400); }
                };
                
                int main(int argc, char *argv[]) {
                    QApplication a(argc, argv);
                
                    Foo foo;
                    foo.setLayout(new QVBoxLayout()); //use a layout for menu bar
                    foo.layout()->setMenuBar(new QMenuBar());
                    foo.layout()->menuBar()->addAction(new QAction("Hi!", &foo));
                
                    QPushButton* p = new QPushButton(&foo); //don't use layout, place it manually
                    p->move(100,100);
                
                    foo.show();
                
                    return a.exec();
                }
                

                If you really don't want the layout for some reason here's the version with main window wrapper, but it's not really necessary:

                #include <QApplication>
                #include <QPushButton>
                #include <QMenuBar>
                
                struct Foo : public QWidget {
                    QSize sizeHint() const override { return QSize(400,400); }
                };
                
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                
                    QMainWindow w;
                    w.setMenuBar(new QMenuBar()); //use the built-in layout for menu bar
                    w.menuBar()->addAction("Hi!");
                    w.setCentralWidget(new Foo); //place the widget in built-in layout
                
                    QPushButton* p = new QPushButton(w.centralWidget());  //place the child manually
                    p->move(100,100);
                
                    w.show();
                
                    return a.exec();
                }
                
                H Offline
                H Offline
                Harry123
                wrote on last edited by Harry123
                #10

                @Chris-Kawa

                I tested and this works, but there is a problem with the menubar now obscuring the upper part of the widget.

                First, this would require modifying all paint functions using absolute coordinates to add a vertical offset equal to the height of the menubar, which is not a simple a job.

                Second, it requires manually increasing the height of the widget.

                These entail the kind of assumptions on my part regarding the GUI which I try to avoid. I prefer to let Qt do this kind of calculations, for portability.

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

                  Ok then, you can use the second variant. QMainWindow will do the calculations for you, but...

                  First, this would require modifying all paint functions (...) which is not a simple a job.

                  Actually it's a one-liner:

                  void Widget:: paintEvent(QPaintEvent* evt) {
                      QPainter p(this);
                      p.setTransform(QTransform::fromTranslate(0, layout()->menuBar()->height()));
                      //paint as usual
                  }
                  

                  Second, it requires manually increasing the height of the widget. These entail the kind of assumptions on my part regarding the GUI which I try to avoid.

                  No assumptions needed:

                  QSize sizeHint() const override { return QSize(400, 400 + layout()->menuBar()->height()); }
                  

                  If you're extra paranoid you can also check layout and menubar for nullpointers, but that's not really necessary here.

                  H 1 Reply Last reply
                  2
                  • Chris KawaC Chris Kawa

                    Ok then, you can use the second variant. QMainWindow will do the calculations for you, but...

                    First, this would require modifying all paint functions (...) which is not a simple a job.

                    Actually it's a one-liner:

                    void Widget:: paintEvent(QPaintEvent* evt) {
                        QPainter p(this);
                        p.setTransform(QTransform::fromTranslate(0, layout()->menuBar()->height()));
                        //paint as usual
                    }
                    

                    Second, it requires manually increasing the height of the widget. These entail the kind of assumptions on my part regarding the GUI which I try to avoid.

                    No assumptions needed:

                    QSize sizeHint() const override { return QSize(400, 400 + layout()->menuBar()->height()); }
                    

                    If you're extra paranoid you can also check layout and menubar for nullpointers, but that's not really necessary here.

                    H Offline
                    H Offline
                    Harry123
                    wrote on last edited by Harry123
                    #12

                    @Chris-Kawa

                    I'm learning a lot from your answers, but regarding "No assumptions needed", there is one big assumption here - that the menubar is part of the widget and is displayed on top.

                    I never programmed on the Mac or Android, but I'm not too sure that this assumption will hold there or on all other platforms where Qt was or will be ported.

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

                      @Harry123 said:

                      there is one big assumption here

                      Right. I'm not an expert on other platforms either. I think the menu can indeed not be a part of the window at least on Mac.
                      Ok then. The wrapper option should still be valid in these scenarios.

                      1 Reply Last reply
                      0
                      • mrjjM mrjj

                        @Harry123
                        Good luck.
                        Note.
                        I just added layout to mainwindow and then a widget. ( the green one)
                        So its not directly on centralwidget.

                        H Offline
                        H Offline
                        Harry123
                        wrote on last edited by
                        #14

                        @mrjj

                        You solution works, and works beautifully. And what's more, is probably almost guaranteed to work on all future versions of Qt.

                        So it's a hack, but who cares, as long as it works so well and is so easy to implement.

                        1 Reply Last reply
                        0
                        • N n__c referenced this topic on

                        • Login

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