How to centre align a widget using QHBoxLayout?
-
I am using an HBoxLayout to layout a set of buttons in the top bar of the application. I need one button be to at the centre, but the layout changes its position if the width of items on the left and right is not exactly the same. Following is my code
#include "mainwindow.h" #include <QHBoxLayout> #include <QPushButton> #include <QVBoxLayout> class MyWidget: public QWidget { public: MyWidget(QWidget* p): QWidget(p) { auto v = new QVBoxLayout; QHBoxLayout* l = new QHBoxLayout; auto b1 = new QPushButton(this); auto b2 = new QPushButton(this); auto b3 = new QPushButton("Misaligned", this); auto b4 = new QPushButton(this); auto b5 = new QPushButton(this); b1->setFixedWidth(90); b2->setFixedWidth(120); b3->setFixedWidth(300); b4->setFixedWidth(35); b5->setFixedWidth(90); l->addWidget(b1, 0, Qt::AlignLeading); l->addWidget(b2, 0, Qt::AlignLeading); l->addStretch(); l->addWidget(b3, 0, Qt::AlignHCenter); l->addStretch(); l->addWidget(b4, 0, Qt::AlignTrailing); l->addWidget(b5, 0, Qt::AlignTrailing); QHBoxLayout* l2 = new QHBoxLayout; { auto b1 = new QPushButton("Aligned" ,this); b1->setFixedWidth(300); l2->addWidget(b1,0,Qt::AlignHCenter); } v->addLayout(l); v->addLayout(l2); setLayout(v); } }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setCentralWidget(new MyWidget(this)); } MainWindow::~MainWindow() { }
How can I ensure that the middle button stays at the centre (as in the bottom row) even if the buttons to the left/right have different widths?
-
I am using an HBoxLayout to layout a set of buttons in the top bar of the application. I need one button be to at the centre, but the layout changes its position if the width of items on the left and right is not exactly the same. Following is my code
#include "mainwindow.h" #include <QHBoxLayout> #include <QPushButton> #include <QVBoxLayout> class MyWidget: public QWidget { public: MyWidget(QWidget* p): QWidget(p) { auto v = new QVBoxLayout; QHBoxLayout* l = new QHBoxLayout; auto b1 = new QPushButton(this); auto b2 = new QPushButton(this); auto b3 = new QPushButton("Misaligned", this); auto b4 = new QPushButton(this); auto b5 = new QPushButton(this); b1->setFixedWidth(90); b2->setFixedWidth(120); b3->setFixedWidth(300); b4->setFixedWidth(35); b5->setFixedWidth(90); l->addWidget(b1, 0, Qt::AlignLeading); l->addWidget(b2, 0, Qt::AlignLeading); l->addStretch(); l->addWidget(b3, 0, Qt::AlignHCenter); l->addStretch(); l->addWidget(b4, 0, Qt::AlignTrailing); l->addWidget(b5, 0, Qt::AlignTrailing); QHBoxLayout* l2 = new QHBoxLayout; { auto b1 = new QPushButton("Aligned" ,this); b1->setFixedWidth(300); l2->addWidget(b1,0,Qt::AlignHCenter); } v->addLayout(l); v->addLayout(l2); setLayout(v); } }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setCentralWidget(new MyWidget(this)); } MainWindow::~MainWindow() { }
How can I ensure that the middle button stays at the centre (as in the bottom row) even if the buttons to the left/right have different widths?
@schrute
I have a feeling this is not going to work/is going to be difficult as long as you have 5 separate widgets. Your left-hand pair are wider than your right-hand pair, hence the behaviour you see.I don't know whether there is a better way (different stretch factors than all being 0 in your
addWidget()
calls), but my first thought would be to create aQWidget
to hold the lefthand pair and another to hold the righthand pair, set those to have a fixed width(?), and then lay out your now 3 widgets with stretches between them oraddWidget()
with equal stretch factors?It can help to play with your attempts in Designer. If you can get what you want that way you can look at its generated code for what to do in code yourself instead.
-
I am using an HBoxLayout to layout a set of buttons in the top bar of the application. I need one button be to at the centre, but the layout changes its position if the width of items on the left and right is not exactly the same. Following is my code
#include "mainwindow.h" #include <QHBoxLayout> #include <QPushButton> #include <QVBoxLayout> class MyWidget: public QWidget { public: MyWidget(QWidget* p): QWidget(p) { auto v = new QVBoxLayout; QHBoxLayout* l = new QHBoxLayout; auto b1 = new QPushButton(this); auto b2 = new QPushButton(this); auto b3 = new QPushButton("Misaligned", this); auto b4 = new QPushButton(this); auto b5 = new QPushButton(this); b1->setFixedWidth(90); b2->setFixedWidth(120); b3->setFixedWidth(300); b4->setFixedWidth(35); b5->setFixedWidth(90); l->addWidget(b1, 0, Qt::AlignLeading); l->addWidget(b2, 0, Qt::AlignLeading); l->addStretch(); l->addWidget(b3, 0, Qt::AlignHCenter); l->addStretch(); l->addWidget(b4, 0, Qt::AlignTrailing); l->addWidget(b5, 0, Qt::AlignTrailing); QHBoxLayout* l2 = new QHBoxLayout; { auto b1 = new QPushButton("Aligned" ,this); b1->setFixedWidth(300); l2->addWidget(b1,0,Qt::AlignHCenter); } v->addLayout(l); v->addLayout(l2); setLayout(v); } }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setCentralWidget(new MyWidget(this)); } MainWindow::~MainWindow() { }
How can I ensure that the middle button stays at the centre (as in the bottom row) even if the buttons to the left/right have different widths?
-
@schrute As Jon pointed out, layout the left helper widget to the left and right helper widget to the right. Then layout the middle one in the center.
@JoeCFD @JonB I tried your suggestion and created three helper widgets that contain the buttons on the left, middle and right, but how do I ensure that the these helper widgets always are of the same width?
Following is the modified code -#include "mainwindow.h" #include <QHBoxLayout> #include <QPushButton> #include <QVBoxLayout> void setBackground(QWidget* w, QColor c) { QPalette p = w->palette(); p.setColor(QPalette::All, QPalette::Background, c); w->setPalette(p); w->setAutoFillBackground(true); } class MyWidget: public QWidget { public: MyWidget(QWidget* p): QWidget(p) { QHBoxLayout* l1 = new QHBoxLayout; QHBoxLayout* l2 = new QHBoxLayout; QHBoxLayout* l3 = new QHBoxLayout; auto b1 = new QPushButton(this); auto b2 = new QPushButton(this); auto b3 = new QPushButton("Misaligned", this); auto b4 = new QPushButton(this); auto b5 = new QPushButton(this); QWidget* left = new QWidget(this); setBackground(left, Qt::red); QWidget* middle = new QWidget(this); setBackground(middle, Qt::blue); QWidget* right = new QWidget(this); setBackground(right, Qt::green); QHBoxLayout* master = new QHBoxLayout; master->addWidget(left, 33); master->addWidget(middle, 33); master->addWidget(right, 33); b1->setFixedWidth(90); b2->setFixedWidth(120); b3->setFixedWidth(300); b4->setFixedWidth(35); b5->setFixedWidth(90); l1->addWidget(b1, 0, Qt::AlignLeading); l1->addWidget(b2, 0, Qt::AlignLeading); l1->addStretch(); left->setLayout(l1); l2->addWidget(b3, 0, Qt::AlignHCenter); middle->setLayout(l2); l3->addStretch(); l3->addWidget(b4, 0, Qt::AlignTrailing); l3->addWidget(b5, 0, Qt::AlignTrailing); right->setLayout(l3); setLayout(master); } }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setCentralWidget(new MyWidget(this)); } MainWindow::~MainWindow() { }
It works as expected at the default window size but when I resize, the helper widgets resize differently and the button in the middle becomes misaligned.
-
@JoeCFD @JonB I tried your suggestion and created three helper widgets that contain the buttons on the left, middle and right, but how do I ensure that the these helper widgets always are of the same width?
Following is the modified code -#include "mainwindow.h" #include <QHBoxLayout> #include <QPushButton> #include <QVBoxLayout> void setBackground(QWidget* w, QColor c) { QPalette p = w->palette(); p.setColor(QPalette::All, QPalette::Background, c); w->setPalette(p); w->setAutoFillBackground(true); } class MyWidget: public QWidget { public: MyWidget(QWidget* p): QWidget(p) { QHBoxLayout* l1 = new QHBoxLayout; QHBoxLayout* l2 = new QHBoxLayout; QHBoxLayout* l3 = new QHBoxLayout; auto b1 = new QPushButton(this); auto b2 = new QPushButton(this); auto b3 = new QPushButton("Misaligned", this); auto b4 = new QPushButton(this); auto b5 = new QPushButton(this); QWidget* left = new QWidget(this); setBackground(left, Qt::red); QWidget* middle = new QWidget(this); setBackground(middle, Qt::blue); QWidget* right = new QWidget(this); setBackground(right, Qt::green); QHBoxLayout* master = new QHBoxLayout; master->addWidget(left, 33); master->addWidget(middle, 33); master->addWidget(right, 33); b1->setFixedWidth(90); b2->setFixedWidth(120); b3->setFixedWidth(300); b4->setFixedWidth(35); b5->setFixedWidth(90); l1->addWidget(b1, 0, Qt::AlignLeading); l1->addWidget(b2, 0, Qt::AlignLeading); l1->addStretch(); left->setLayout(l1); l2->addWidget(b3, 0, Qt::AlignHCenter); middle->setLayout(l2); l3->addStretch(); l3->addWidget(b4, 0, Qt::AlignTrailing); l3->addWidget(b5, 0, Qt::AlignTrailing); right->setLayout(l3); setLayout(master); } }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setCentralWidget(new MyWidget(this)); } MainWindow::~MainWindow() { }
It works as expected at the default window size but when I resize, the helper widgets resize differently and the button in the middle becomes misaligned.
@schrute
try this:l1->addWidget(b1, 0, Qt::AlignLeft); l1->addWidget(b2, 0, Qt::AlignRight); //l1->addStretch(); left->setLayout(l1); l2->addWidget(b3, 0, Qt::AlignHCenter); middle->setLayout(l2); //l3->addStretch(); l3->addWidget(b4, 0, Qt::AlignRight); // or left ? l3->addWidget(b5, 0, Qt::AlignLeft); // or right ? right->setLayout(l3);