How to pin widget to left/right/top/bottom edge?
-
Hi everyone,
Today question from UI's modeling.
I'd like to dynamicly display different QWidget Form in one area of Form. Simple preview:
Main area to load my widgets:
!http://shimano.one.pl/qt/mainform.png(Main area for loading widgets)!
And one of my widgets which will be loaded to that area:
!http://shimano.one.pl/qt/widgetform.png(My widget to load)!
The first thing is, how to force aligning my loaded widget forms to this specified area?
And the second thing is, how to align that widget's area to sides of window? For example, I'd like to pin area to left, top and right edges of window.Another thing is, how to pin each component (object) of my widget's Form to specified side? For example, I'd like to pin button "Add" to left bottom corner of widget's form and other two buttons pin to right bottom corner. And their should stay on its places when user resize window.
As I Googled, this could be done by Layouts in Qt Designer, but everytime I set some layout then buttons are resized, even if I use Horizontal Spacers.
This is very cute solved in Visual Studio, because the only I have to do is to set aligment for each object on Form. Is something similar in Qt Designer?
-
Set the buttons to fixed size, add spacers and all done. There are some good QtDesigner tutorials around. Try then ;-)
-
Am I right you are comming from a .Net'ish world? VS and pinning to sides sounds like it :)
What you describe is closer to what QML in Qt Quick uses.
With Qt widgets it works a little different. You set layouts to widgets and they take care of proper aligning and resizing. There is no pinning to sides etc.A documentation for it is "here":http://qt-project.org/doc/qt-4.8/designer-layouts.html
As a short example:
!http://img17.imageshack.us/img17/7883/layoutgi.jpg(layouts example)!The blue bars icons indicate that a layout is set, either horizontal or vertical. It basically indicates if items are stacked top to bottom or side by side. There is also a grid layout and form layout (not used here). To "push" items you use spacers (I call them springs :) ).
-
bq. All objects stay static
What a lot of Qt starters forget is to set the layout of the top widget. Select the widget you placed and click the e.g. horizontal layout. This will set the Widget layout just as Chris indicated above with a QMainWindow which is a fancy form of a Widget. The widget will now do resizing etc and all its childern will comply to that action.
Greetz -
Ok... Seems it's working...
Now little harder thing...
I have few "resizable" widget Forms like this:!http://shimano.one.pl/qt/widgetform.png(widget form)!
and main window with "resizable" area where I want to load my widget Forms:
!http://shimano.one.pl/qt/mainform.png(Load anything here)!
I'm loading Forms by:
@
contacts = new ListOfContacts(ui->widget);
contacts->show();
@Question is, how to load this form into widget (or replace with widget) to keep resizability? Size of loaded form should be adjusted to widget's size and resize when user resize main window.
-
You don't "load into a widget". As I said - you use layouts for positioning. Also show() is redundant. The widget will be shown automatically.
So, if ui->widget is your "container", it goes something like this:
@
//you don't need a parent here (but it's ok if it's there too)
//it will be automatically reparented when inserted into a layout anyway
contacts = new ListOfContacts();//create a layout, VBox, HBox, Grid or whatever
//also don't need a parent. it will be reparented when assigned to widget
QVBoxLayout* layout = new QVBoxLayout();//insert your new widget into that layout
layout->addWidget(contacts);//assign this layout to your "container"
ui->widget->setLayout(layout);
@ -
I don't know what's wrong, but it doesn't work for me...
Even I tried replace widget for QGridLayout and just add my widget to GridLayout, but it's not what I want...
This is my main window:
!http://shimano.one.pl/qt/mainlayout.png(main layout)!
And this is my widget:
!http://shimano.one.pl/qt/contactlist.png(ListOfContacts)!
And my best result is (best means, loaded widget is resizable with window):
!http://shimano.one.pl/qt/mainwithcontacts.png(Main window with loaded contact list)!
And this is called by:
@
contact_list = new ListOfContacts(ui->gridLayoutWidget);
ui->gridLayout->addWidget(contact_list);
@But it is not in it's place. Your code above gives similar effect.
-
You're doing some odd things in your main window. Why are you placing a spacer in a splitter? It makes no sense.
Could you say what is it that you want exactly? I don't really get it.
If you just want your contacts widget to fill main window then forget all those layouts and just use mainWindow->setCentralWidget(contacts).
If you really want a resizable area via splitters then you need to put some widgets(or layouts) in that splitter. If there's only a spacer there Qt will assume it's an empty area(without widgets) and show no splitter handle.
So with this kind of layout:
!http://img33.imageshack.us/img33/6499/splitterlayout.jpg(splitter layout)!You can add your widget to any of those areas, eg.
@
ui->topRightAreaLayout->addWidget(contacts);
@
which will give you this:
!http://img51.imageshack.us/img51/7786/splitterwindow.jpg(splitter window)!Windows 8 uses a weird color for splitter handles (transparent :) ) so I used this little stylesheet to show where they really are:
@
setStyleSheet("QSplitter::handle { background-color: red; }");
@