Create Qt layout with fixed height - qt

I want to create a Qt window that contains two layouts, one fixed height that contains a list of buttons at the top and one that fills the remaning space with a layout that centers a widget vertically and horizontally as per the image below.
How should i be laying out my layouts/widgets. Ive tried a few options with nested horizontal and vertical layouts to no avail

Try making the pink box a QWidget with a QHBoxLayout (rather than just making it a layout). The reason is that QLayouts don't provide functionality to make fixed sizes, but QWidgets do.
// first create the four widgets at the top left,
// and use QWidget::setFixedWidth() on each of them.
// then set up the top widget (composed of the four smaller widgets):
QWidget *topWidget = new QWidget;
QHBoxLayout *topWidgetLayout = new QHBoxLayout(topWidget);
topWidgetLayout->addWidget(widget1);
topWidgetLayout->addWidget(widget2);
topWidgetLayout->addWidget(widget3);
topWidgetLayout->addWidget(widget4);
topWidgetLayout->addStretch(1); // add the stretch
topWidget->setFixedHeight(50);
// now put the bottom (centered) widget into its own QHBoxLayout
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addStretch(1);
hLayout->addWidget(bottomWidget);
hLayout->addStretch(1);
bottomWidget->setFixedSize(QSize(50, 50));
// now use a QVBoxLayout to lay everything out
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(topWidget);
mainLayout->addStretch(1);
mainLayout->addLayout(hLayout);
mainLayout->addStretch(1);
If you really want to have two separate layouts--one for the pink box and one for the blue box--the idea is basically the same except you'd make the blue box into its own QVBoxLayout, and then use:
mainLayout->addWidget(topWidget);
mainLayout->addLayout(bottomLayout);

Related

How to control widgets position insid QStackedLayout

I've created a QStackedLayout in which I added 2 buttons, but I want to shift one button to the right corner insted of the left corner as you can see in the picture below:
What I've done so far:
QStackedLayout *stackedLayout = new QStackedLayout;
stackedLayout->addWidget(ui->pushButton_2);
stackedLayout->addWidget(ui->pushButton);
stackedLayout->setStackingMode(QStackedLayout::StackAll);
Place the QPushbutton in a container (i.e. QWidget) that allows it to be centered with an additional layout.
If I understand properly, you want a QPushButton above an other. The one above must be smaller and at the top right corner?
QVBoxLayout * vlayout_PB_under = new QVBoxLayout();
QHBoxLayout * hlayout_PB_under = new QHBoxLayout();
QPushButton * PB_x = new QPushButton("X",this);
QPushButton * PB_test = new QPushButton("test",this);
PB_x ->setFixedSize(20,20);
PB_test ->setFixedSize(200,200);
PB_test ->setLayout(vlayout_PB_under );
vlayout_PB_under ->addLayout(hlayout_PB_under);
hlayout_PB_under->addWidget(PB_x );
vlayout_PB_under ->setAlignment(Qt::AlignRight);
hlayout_PB_under->setAlignment(Qt::AlignTop );
The purpose of a QStackLayout is to allow switching easily the visible widget at a same position, not to display at the same time multiple widget...
Read the documentation : "where only one widget is visible at a time"

How to set a center aligned QLabel to toolbar in Qt

I'm new to qt and exploring it .I want to have a text which is center aligned in my Mainwindow's toolbar.Below is my code inside my MainWindow constructor:
QLabel* label=new QLabel("Hello World");
label->setAlignment(Qt::AlignHCenter);
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(label);
QWidget* wid = new QWidget;
wid->setLayout(layout);
ui->mainToolBar->addWidget(wid);
The above code displays the text , but not at the center.It displays at the left.What am I missing?Any help will be really helpful.
label->setAlignment(Qt::AlignHCenter);
This tells the label to (horizontally) center the text in itself.
layout->addWidget(label);
This is expanded by default argument to
layout->addWidget(label, 0);
Where the 0 is the stretch factor of the label within this layout. Zero means your label will be given as much space as it needs to display properly but nothing more. So your label is just as big as your text needs, has it's text centered, but since it's on a QHBoxLayout it's shown on the left side within your bar. If there are no other widgets in your bar's layout, you can set the stretch-factor to 1 to make the label fill the layout, your text will then show in the center.
layout->addWidget(label, 1);

Allignment of a QLabel and a QCheckBox in a BoxLayout gives unexpected result

when i add a QLabel and QCheckBoxs to either a QVBoxLayout or a QHBoxLayout i would expect them to be evenly distributed but the checkboxes will allign tight at the very bottom (in the above example) and the label will be centered on the resulting free space in the widget. How can i change this behaviour to distribute all 3 widgets evenly?
Many thanks.
This is the example code:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
QLabel* l = new QLabel("Hi");
QCheckBox* c = new QCheckBox("Label");
QCheckBox* c2 = new QCheckBox("Label");
l->setText("Hi");
QVBoxLayout* v = new QVBoxLayout;
v->addWidget(l);
v->addWidget(c);
v->addWidget(c2);
setLayout(v);
ui->setupUi(this);
}
And this is the result:
Take a look at QSizePolicy. You need to setSizePolicy for your QLabel and QCheckBoxes to be QSizePolicy::Preferred, from the docs:
The default policy is Preferred/Preferred, which means that the widget
can be freely resized, but prefers to be the size sizeHint() returns.
Button-like widgets set the size policy to specify that they may
stretch horizontally, but are fixed vertically. The same applies to
lineedit controls (such as QLineEdit, QSpinBox or an editable
QComboBox) and other horizontally orientated widgets (such as
QProgressBar).
Currently, your QLabel has preferred height, while both of the QCheckBoxes has fixed height. That means that the QLabel will be expanded automatically to take up any additional vertical space (that can't be taken by the QCheckBoxes.
So, In order to set all your widgets to Preferred height, you need to add the following to your constructor:
l->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
c->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
c2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
Another option, would be to add spacers around each one of the widgets, like this:
v->addStretch();
v->addWidget(l);
v->addStretch();
v->addWidget(c);
v->addStretch();
v->addWidget(c2);
v->addStretch();
setLayout(v);
This way QSpacerItems will take up all the additional space.

Prevent widgets stretching in QVBoxLayout and have scrollbar appear in QScrollArea?

Making my way up the Qt learning curve, I've seen many questions about dynamic layouts but the solutions aren't working for me or I don't quite understand them.
Reference questions:: Qt Scroll Area does not add in scroll bars, How can i make widgets overflow to make a scrollbar appear in Qt?
Question:: I want to have a dynamic layout of a set of widgets within a QScrollArea. I've been able to do this manually in Qt Creator and now I am trying to do it through code.
How do I prevent the widgets from stretching/force the area to scroll?
How do I have the added widgets start from the top? I have a vertical spacer in my QVBoxLayout but that pushes everything to the bottom.
Simple test code::
void MainWindow::on_pushButton_clicked()
{
ui->myScroll->setWidgetResizable(true); //making sure this is set
QPushButton *b = new QPushButton(this);
b->setText(QString("Hello Button"));
QHBoxLayout *h = new QHBoxLayout();
h->addWidget(b,0);
ui->myVBoxLayout->addLayout(h,0);
}
Result:: Left side squished (dynamic) – Right side Ok (set up manually)
Qt Creator Setup:: Left side: dynamic – Right side set up manually
Properties::
You can set use setMinimumHeight() on your buttons for preventing squished buttons. The layout can be configured with setContentsMargin() for space between item-border and item-content (QtDesigner has all four directions set to 9 IIRC) and setSpacing() for space between items (QtDesigner uses a default of 6). Also setWidgetResizable(true) allows your scrollarea to resize the view widgeth inside the area (this is where your layout and children are being placed).
This works for me:
In constructor or code set scrollArea->widget() to hold the QVBoxLayout:
v = new QVBoxLayout;
ui->scrollArea->widget()->setLayout(v);
In Button Slot:
void MainWindow::pushButtonPressed()
{
ui->scrollArea->setWidgetResizable(true);
QPushButton *b = new QPushButton(this);
b->setText(QString("Hello Button"));
QHBoxLayout *h = new QHBoxLayout();
h->addWidget(b,0);
v->addLayout(h);
}

Two QTableViews in QLayout

I want to expand QTableViews' size so each QTableView takes the half size of the window! , how can i do it?
screenshot:
http://i.stack.imgur.com/Rh87o.jpg
Add a QHBoxLayout to your widget/window and then add the tables to it.
The following code on a top level widget..
QHBoxLayout *horizontalLayout;
QTableView *tableView;
QTableView *tableView_2;
horizontalLayout = new QHBoxLayout(Widget);
tableView = new QTableView(Widget);
horizontalLayout->addWidget(tableView);
tableView_2 = new QTableView(Widget);
horizontalLayout->addWidget(tableView_2);
Will give you something like..
The two tables share the available space equally and expand and resize with the main window.

Resources