Cannot align items to top in scroll area Qt - qt

In a Qt Widget Application, I'm trying to make the following:
My aim is to have a form with a scrollArea with a vertical layout and each item in the scroll area aligned at the top.
Unfortunately, it's only staying in the centre shown here:
I've tried selecting the scrollArea and chaninging vertical alignment from AlignVCenter to AlignTop, but this seems to have no effect.
How can I align all the content to the top of the scroll box?

You can use a QListWidget to hold a list of not only just text, but also QWidget's (such as push buttons, line edits, etc).
Simply add a QListWidget to your window, and in C++ add the widgets to the QListWidget as needed.
Here are some steps to insert a button into your QListWidget:
Create a QListWidget item into your application.
change selectionMode = NoSelection and focusPolocy = NoFocus
Put the following C++ code into your application:
// Create list item
QListWidgetItem *listWidgetItem = new QListWidgetItem();
// Create widget
QWidget *widget = new QWidget();
QVBoxLayout *verticalLayout = new QVBoxLayout();
verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
widget->setLayout(verticalLayout);
// Add button to widget layout
QPushButton *pushButton = new QPushButton("Button!");
verticalLayout->addWidget(pushButton);
// Add list item to ul->listWidget
listWidgetItem->setSizeHint(widget->sizeHint()); // Set the size of the list item to the same as the widget
ui->listWidget->addItem(listWidgetItem);
ui->listWidget->setItemWidget(listWidgetItem, widget);
Old answer:
I found my answer here but I will re-post it for anyone else interested.
To align elements at the top of a scroll area, add a vertical layout as a child to the scroll area and put all your elements inside that vertical layout. Like so:
In your C++, add a spacer item to your vertical layout inside the scroll area by using addStretch():
ui->verticalLayout->addStretch();
All the items should now magically be aligned to the top.
Edit:
This seems to only work for the very first item, and all other items are not pushed up to the top.

Related

Adding/removing items from a QT layout

I'm trying to add some items dynamically to a vertical layout, so I'm creating a new horizontal layout, adding a label and push button to that, then adding this to the vertical layout using addLayout, but it doesn't seem to be happening correctly.
If i put a breakpoint in and go through the 'this' object's children, I find the vertical layout object, and it has the push button and label as children - no horizontal layout object to be seen, but in the GUI it is being layed out like it's in a horizontal layout (yes the naming convention here is bad).
QHBoxLayout *AA = new QHBoxLayout;
QLabel *BB = new QLabel;
QPushButton *CC = new QPushButton;
AA->addWidget(BB);
AA->addWidget(CC);
ui->verticalLayout->addLayout(AA);
I then try to remove the buttons from the horizontal layout and remove the horizontal layout and delete them, but depending upon how I do it, it either doesn't work or crashes.
QHBoxLayout *a1 = ui->verticalLayout->layout()->findChild<QHBoxLayout*>();
QPushButton *a2 = ui->verticalLayout->findChild<QPushButton*>();
QPushButton *a3 = a1->findChild<QPushButton*>();
//(a2 and a3 are both null, a1 returns an object)
So my question is how do I add items dynamically to a horizontal layout then add this to an existing layout, and then later iterate through this to remove them? (One unfortunate thing I've found with Qt thus far is tutorials or 'how tos' for dynamic layouts is completely lacking, most things I've tried have came from posts on SO).

Qt-designer: enlarging the window does not replace my items

To keep the question as simple as possible, I prepared a simple Qt designer form below
There is a Tab Widget on the left side and empty QWidget on the right side, the QWidget as a GroupBox. The Groupbox has a radio and pusbuttons (you can see them on Object inspector window on the photo as well ). The tab widget has a line edit. The central widget has a gridlayout and horizontal qsplitter is used.
My issue is that when I enlarge the window, all items (lineedit, radiobutton, pushbutton) are on the fix position. Here is an example what I mean:
What I want is that when the window is enlarged the items should be placed on the bottom of the window, or if they are in the middle, then they should stay in the middle. ( I don't want size of the buttons/lineedits to be changed).
How can I do it?
The items you want to move dynamically, with window resizing must be in a layout.
So, in the example you've posted, you need two layouts; one inside the tab widget, for the QLineEdit and at least one in the GroupBox for the radio button and push button.
If you want the radio and push button to be aligned horizontally, you can start by placing them in a horizontal layout, before placing that layout in another, which all reside in the group box.
When you start to add items to layouts, such as push buttons, you'll start to notice that they can get stretched, so you may need to set the size policies of the widgets.
If you want the line edit to be centered horizontally, you will have to place two horizontal spacers on each side of the line edit and select the three together and set "Lay out Horizontally". This can found at the top toolbar in Qt Designer.
To always have it at the bottom of the tab widget, put a vertical spacer above the line edit in your tab widget. Then select the option "Lay out vertically" for the tab widget.
The same goes for your radio button and push button. Keep them in a horizontal layout, with horizontal spacers if required and put a vertical spacer into the group box and set the layout property for the group box as "Lay out Vertically".
Most important of all, I suggest you go through some basic tutorials before you continue. Here is a link to a good channel on youtube.
https://www.youtube.com/playlist?list=PL2D1942A4688E9D63
If you don't have a layout in your tabWidget or GroupBox:
You must set a layout (for example QVBoxLayout) inside your tab widget and a group box.
It can be done using QtDesigner. It also can be done in code like this:
QWidget *window = new QWidget;
QPushButton *button1 = new QPushButton("One");
QPushButton *button2 = new QPushButton("Two");
QPushButton *button3 = new QPushButton("Three");
QPushButton *button4 = new QPushButton("Four");
QPushButton *button5 = new QPushButton("Five");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
layout->addWidget(button5);
window->setLayout(layout);
But if you do, and then you want your buttons to stay at the bottom:
Then you have to try setRowStretch method http://qt-project.org/doc/qt-4.8/qgridlayout.html#setRowStretch or take a look at QSpacerItem.

Setting the sizepolicy in qt

I have a widget and a graphics view in the central widget of my application. The widget has four push buttons in it. I added the both in horizontal layout using the following code:
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(ui->entityWidget);
layout->addWidget(ui->graphicsView);
ui->centralWidget->setLayout(layout);
I have set the size policy of the widget to be minimum and that of the graphics view to preferred. When I run the app, the widget is displayed appropriately in the top left corner but the graphics view's top left corner is in the middle of the central widget, which is not required. It should be right next to the widget.
How do I modify the size policy for correct placement of the graphics view in the main window?
It looks like you're not setting a parent widget to the Layout. That's likely your problem.
Try:
QHBoxLayout *layout = new QHBoxLayout(ui->centralWidget);
layout->addWidget(ui->entityWidget);
layout->addWidget(ui->graphicsView);
ui->centralWidget->setLayout(layout);
Also, if you post how your setting the SizePolicy that would help.
Just add a stretch to the layout right after the graphicsView:
layout->addStretch();

Qt ScrollArea on widget messes up size and position of widget [Qt 5.1]

I'm new with Qt and I want to implement a scrollable widget which can grow dynamically, e.g. by adding buttons into it when another button is pressed. I try to implement it using the following layout and code:
scrollArea = new QScrollArea(ui->outerWidget);
scrollArea->setWidget(ui->innerWidget);
layout = new QVBoxLayout(ui->outerWidget);
ui->innerWidget->setLayout(layout);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// code for PushButton to add buttons in innerWidget
void MainWindow::on_pushButton_clicked()
{
QPushButton *button = new QPushButton("button"+QString::number( nameCounter ));
nameCounter ++;
ui->innerWidget->layout()->addWidget(button);
}
This implementation has two problems when I run the program, first the innerWidget appears out of place (I define its position in Qt Creator's Design mode) and second after many widgets are added in the layout the scroll bar is doesn't grow, but instead the widgets are become smaller to fit into the layout:
In another thread it was suggested to set widgetResizable to true:
scrollArea->setWidgetResizable(true);
The scroll bar seems to work now but the new problem is that the innerWidget becomes very small so it is barely visible:
So, how can I achieve a scrollable widget that will respect the size and position of the design?
have no environment to verify but good luck.
to place scrollArea the target position,
Manually call SetGeometry, or
Place a QScrollArea in ui form, (suggested if it's static), or
Place a widget in your target position, and set QScrollArea's parent to it, and add QScrollArea to its layout, and Set QScrollArea to be expanding.
manually create a QWidget innerWidget and assign it to scrollArea via QScrollArea::setWidget(*QWidget), try different size policy to innerWidget, such as "Preferred".
Also be aware of Qt's reference mentioned : void QScrollArea::setWidget ( QWidget * widget )
Sets the scroll area's widget.
....
Note that You must add the layout of widget before you call this function; if you add it later, the widget will not be visible - regardless of when you show() the scroll area. In this case, you can also not show() the widget later.
Above list solutions, below are reasons to the problems you mentioned:
scrollArea->setWidget(ui->innerWidget); Setting a widget to ScrollArea will change the parenting and layouting of ui->innerWidget, so the geometry values written in ui form (in Qt Creater) will no longer take effect, this is the reason of innerWidget out of place. ui->innerWidget is no longer a child of outerWidget, it's geometry will follow its new parent (but not scrollArea, there's some tricky layouting inside QScrollArea". To be clear, innerWidget is not helpful to locate scrollArea in such scenario.
In your first clip of code, widget 'scrollArea' is created with parent outerWidget, again no size policy or layout or geometry is specified, so scrollArea will by default be placed at the left top corner of the parent "outerWidget". To place scrollArea to your target geometry, you can " set geometry manually " or " assign innerWidget as scrollArea's parent and expand scrollArea". Obviously the latter method cannot assign ui->innerWiget to scrollArea->setWidget().
scrollArea->setWidgetResizable(true); makes the scrollArea "shrink" at left top corner of outerWidget. This is because, QScrollArea does not increase along with it's contents, it can scroll to display all of it contents so the required size of QScrollArea can be as small as possible. Once the 'Resizable' property is set to "true", QScrollArea decides to shrink to its minimum necessary size, thus the size to display its scroll bar and scroll buttons....

reducing the width of QMenuBar and QToolBar in mainWindow

In my MainWindow ,menuBar contents and toolBar contents are few that it will occupy only a small portion in the left side off the main window and the rest of the portion is left empty.
Im having a info frame with some widgets in it in the right side of the centerwidget.
my question is that can i use the the info frame from the menu bar space itself
as menubar and toolbar can occupy only left portion of the mainwindow and i can use the entire right portion for info frame..?
You can't use that space through layout because this space is already taken by the main menu and the toolbar. There is no option to put something in this space.
But you can add a main window's child without putting it in any layout. It will be shown above all layed out children. But you will have to calculate and adjust size and position of this widget manually.
For example, add the following code to the main window's constructor:
QPushButton* b = new QPushButton("TEST", this);
b->move(200, 0);
It looks like this:

Resources