Good morning,
I have to layout some QWidgets and layouts into a main layout, but I have a problem with a space that I can not remove.
Basically what I would achieve is a horizzontal layout containing a grid layout and some buttons ( all in a horizontal line ). The grid layout (2x2) contains 2 QLabels and 2 QLeds.
Unfortunately Qt place a space between the grid layout and the first button as you can see in the attached image here http://img413.imageshack.us/img413/9132/problemhu.png
I would remove such space.
Here the code I wrote:
QGridLayout* gl = new QGridLayout();
gl->setAlignment(Qt::AlignLeft);
gl->setContentsMargins(0, 0, 0, 0);
gl->addWidget(activeLabel, 0, 0);
gl->addWidget(m_focusLed, 0, 1);
gl->addWidget(encodingLabel, 1, 0);
gl->addWidget(m_encodingLed, 1, 1);
This created the grid layout and added the QLabels and QLeds on it.
Then I add the buttons into the horizontal layout so:
/* layout buttons */
QHBoxLayout* lo = new QHBoxLayout();
lo->setSpacing(0);
lo->addLayout(gl); // <--here I add the grid layout
lo->addWidget(m_goToBeginBtn);
lo->addWidget(m_goToEndBtn);
lo->addWidget(m_frewBtn);
lo->addWidget(m_fforBtn);
lo->addSpacing( 10 );
lo->addWidget(m_ffrewBtn);
lo->addWidget(m_ffforBtn);
lo->addSpacing(10);
lo->addWidget(m_prevBtn);
lo->addWidget(m_nextBtn);
lo->addWidget(m_playBtn);
lo->addWidget(m_stopBtn);
lo->addWidget(m_cutBtn);
lo->addSpacing(10);
lo->addWidget(m_zoomInBtn);
lo->addWidget(m_zoomOutBtn);
lo->addSpacing(10);
lo->addWidget(m_bgSndCheckBox);
lo->addWidget( m_showPanelBtn);
I don't know why Qt place such space between the grid layout and the first button. I would remove it. How can I do? I didn't get help from the Qt mailing list.
Best Regards
How to fix this largely depends on what behavior you want to see. I'm guessing what you want is for the labels and the Leds to stay exactly where they are, and keep their size.
What is happening is that the grid layout is resizing with your window, (like your buttons), but the left alignment is keeping the controls stuck to the left, thus the space.
First, remove the gl->setAlignment(Qt::AlignLeft) line.
Secondly, you want to make sure you set the sizePolicy properly on both your QLabels and your QLeds, because otherwise your QLeds will start to resize horizontally. What you want is a fixed horizontal size policy. Here is an example:
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
label->setSizePolicy(sizePolicy);
A completely different way to accomplish the same thing would be to add a bunch of calls to setStretch() on your horizontal layout. But you would have to do this for each column in your layout that you want to stretch. Basically each for each button, but skipping the grid layout in the first column. Like this...
lo->setStretch(1, 1); // Column 1 is your first button
lo->setStretch(2, 1);
...
lo->setStretch(19, 1)l // 19 columns in total, 15 buttons plus 4 spacing.
Related
I'm using Qt Designer to create a graphic interface, but i am struggling to do a basic operation.
I want to create a vertical layout in which there are 2 (or more) horizontals layouts. But if I try to grab my horizontal layouts to put them in the vertical one, the first horizontal layout ends up taking all the space in vertical layout, so i can't add the second one other than inside the first hozitontal layout.
I end up with Horizontal layout 1 in Horizontal layout 2 in Vertical layout which is not what i want
here is the picture or what i get :
VS what i want :
I tried to do it through the Tree object at the right, but it seems we can't drag and drop objets there nor can i copy and paste it to change the ancestor. Is there any way to do it other than editing the XML file ?
One fewer horizontal layout (spacers added for clarity):
Cause
Qt Designer sets the margins of the newly added layouts to 0, 0, 0, 0, so it is impossible to target with the mouse a 0px-wide area when you try to add something to the layout.
Solution
Change the margins of the layout temporarily to something, which is comfortable for you to hit with the mouse. Then you can easily drag and drop new items to this layout. Later you could change the margins back to 0.
I have just started using Qt (5.3) and encountered the fact that some controls appears with margins which I cannot control.
First, I tried to put QLabel and QPushButton right inside QMainWindow
window = new QMainWindow;
label = new QLabel( title, window );
In this case label appears with a margin of 12 pixels at the top (see picture).
QPushButton appears with 1 pixel top & left margins.
But if I insert QFrame with a border, it appears without any margin.
So the margins seem to be attributes of QLabel and QPushButton.
BUT:
When I tried to add extra QFrame between windows and controls:
window = new QMainWindow;
frame = new QFrame(window );
label = new QLabel( title, frame);
I had got different picture:
QLabels top margin had shortened to 1 pixel
QPushButton 1 pixel margins remained intact, but the height of the button had changed
I have tried:
setStyleSheet( "padding:0px" )
and
setContentsMargins( 0, 0, 0, 0 )
for all elements, but without any success.
Any help would be greatly appreciated
The QMainWindow class isn't designed to have widgets added to it directly. Whatever results you see are due to this fact.
The "margins" that you see are not really margins. Since a QLabel is a QFrame, you can enable its frame to see that it has no margin - merely the text is offset from the edge, and that's by design. You can similarly overlay a same-size translucent rectangle on a QPushButton to see that there is also no margin, merely the styling adds its own platform-specific margin. Do not mistake the platform styling mechanism for the style sheets: they are two separate mechanisms and mostly exclusive, with the use of the latter disabling the effects of the former, with few exceptions. For example, the stylesheet spacing/margins/padding is additive to whatever the platform style mandates.
See this answer for an example of how to show overlays on any widget without subclassing.
I'm trying to make a sign-in form with Qt5.0.1. I created 2 Widgets and I put my labels and line edits in one of them, and my button in other one. Then I put these 2 widgets in a QVBoxLayout, but the space between two widget in layout is more than purpose. I tried setSpacing and setContentsMargin but they didn't work for this program.
vhandle->setSpacing(0);
vhandle->setMargin(0);
vhandle->setContentsMargins(0,0,0,0);
vhandle->addWidget(handle,0, Qt::AlignTop);
vhandle->addWidget(handle2,0, Qt::AlignTop);
but nothing changed in space between two widgets:
what should I do?
The issue is not the margin settings of the QVboxLayout, but the margin settings of the layout of your container widgets and the spacing setting of the QVBoxLayout. You already have set the spacing to 0, this should be fine. In addition, assumed that upperWidgetLayout is the layout of the upper widget and lowerWidgetLayout the layout of the lower widget, try
upperWidgetLayout->setContentsMargins(-1, -1, -1, 0);
lowerWidgetLayout->setContentsMargin(-1, 0, -1, -1);
This sets the bottom margin of the upper widget's layout and the top margin of the lower widget's layout to 0, so that there is no space between the contents of the two widgets:
Temporarily coloring the various widgets is usually a good approach to track down such issues. You can also use Qt Designer to design the UI and have a look at the source code which is being generated (or use the .ui file directly in your project).
The extra space between widgets or layout can be removed by setting the alignment at top here is an example:
self.layout_scrollarea_v=QVBoxLayout(self.frame)
self.layout_scrollarea_v.setAlignment(Qt.AlignTop)
self.layout_scrollarea_v.addLayout(self.layout_scrollarea_h1)
self.layout_scrollarea_v.addLayout(self.layout_scrollarea_h3)
self.layout_scrollarea_v.addLayout(self.layout_scrollarea_h2)
in your code use
vhandle->setAlignment(Qt::AlignTop)
In my QGraphicsView, I display a map. I need to display a horizontal ruler and a vertical ruler on the top edge and left edge respectfully.
The map needs to scrolled but the above rulers should be displayed at their fixed positions, but change their scale values.
I tried to implement this using drawForeground method. Due to the maps large size I only paint the visible area. So I need to update() every time scrolling is done. But this result sometimes flickers.
I feel it would be best to have separate layer like approach.
What is the best way to approach the problem?
The correct way to implement a ruler on the top and left is to derive from QGraphicsView, and then call in the constructor:
// add two rulers on top and left.
setViewportMargins(20, 20, 0, 0);
// add grid layout
QGridLayout* gridLayout = new QGridLayout();
gridLayout->setSpacing(0);
gridLayout->setMargin(0);
// create rulers
hRuler = new Ruler(Qt::Horizontal);
vRuler = new Ruler(Qt::Vertical);
// add items to grid layout
QWidget* corner = new QWidget();
corner->setBackgroundRole(QPalette::Window);
corner->setFixedSize(20, 20);
gridLayout->addWidget(corner, 0, 0);
gridLayout->addWidget(hRuler, 0, 1);
gridLayout->addWidget(vRuler, 1, 0);
gridLayout->addWidget(viewport(), 1, 1);
// finally set layout
setLayout(gridLayout);
This solution was initially presented here, and it works very well. The result looks like this.
I just changed ViewportUpdateMode of the graphics view to FullViewportUpdate to get away from flicker.
You can use SmartViewportUpdate for somewhat good results also.
The downside is, during animations, this takes more process power.
I'm trying to layout a window (all in code) with a QGridLayout. I can add widgets to the layout and they display in my window, but I can't figure out how to resize them properly. Here's what I'd like
[Leftmost][--------Center---------][Rightmost]
Those are the 3 "panes" of my window (all three of them lists). The left and right ones should be of a static width and hug their respective sides, and the center should expand to fill the width as the window grows (or shrinks).
Some code:
// Create the subviews, add them to a grid layout, and set the layout to the window.
QTableView *list = new QTableView(0);
list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QTableView *flashList = new QTableView(0);
flashList->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QPushButton *infoButton = new QPushButton("Info!");
QPushButton *flashFeedsButton = new QPushButton("Flashfeeds");
QGridLayout *gridLayout = new QGridLayout;
// Set the minimum widths for all three columns of the grid
gridLayout->setColumnMinimumWidth(GridColumnFirst, 300);
gridLayout->setColumnMinimumWidth(GridColumnSecond, 300);
gridLayout->setColumnMinimumWidth(GridColumnThird, 300);
// Set the minimum heights for all rows of the grid
int headerFooterHeight = 44;
gridLayout->setRowMinimumHeight(GridRowFirst, headerFooterHeight);
gridLayout->setRowMinimumHeight(GridRowSecond, 200);
gridLayout->setRowMinimumHeight(GridRowThird, headerFooterHeight);
// Set the stretch factors
gridLayout->setColumnStretch(GridColumnFirst, 1);
gridLayout->setColumnStretch(GridColumnFirst, 2);
gridLayout->setColumnStretch(GridColumnThird, 1);
gridLayout->addWidget(list, 1, 0, Qt::AlignLeft);
gridLayout->addWidget(flashList, 1, 1, Qt::AlignCenter);
gridLayout->addWidget(infoButton, 0, 3, Qt::AlignRight);
gridLayout->addWidget(flashFeedsButton, 0, 1, Qt::AlignLeft);
_mainWindow->setLayout(gridLayout);
(As you might be able to tell, this is going to eventually be a 9x9 grid, but the point remains, I'm trying to get my middle row (GridRowSecond) to have the stretchy columns).
The rows themselves expand just fine. The problem seems to be getting the widgets at each cell to expand to take up their containing space. How do I do this? (also, vertically, my list is expanding properly, but not horizontally).
Look at the docs on QGridLayout::AddWidget:
The default alignment is 0, which means that the widget fills the entire cell.
But you have the following:
gridLayout->addWidget(list, 1, 0, Qt::AlignLeft);
gridLayout->addWidget(flashList, 1, 1, Qt::AlignCenter);
gridLayout->addWidget(infoButton, 0, 3, Qt::AlignRight);
gridLayout->addWidget(flashFeedsButton, 0, 1, Qt::AlignLeft);
Thus, you've specifically told the grid layout that you want your widget aligned to the left, center, right, and left of their cells, respectively. In your case you probably want to use the default alignment allowing the widgets to fill the cells and follow their own respective size policies.
It should just be a matter of setting the proper size policy on your widgets. So the buttons on the left and right:
button->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
and for the middle button
button->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
where the first argument defines the horizontal size policy and the second one defines the vertical size policy.
See the size policy documentation as well
You have a lot of variables going here (different widgets, different size policies on widgets, and size policies working on the layout itself, so it's a bit difficult to know where things are going wrong. A couple of suggestions:
1) First try to accomplish what you want with just one type of widget. For example, all QLabels with all Expanding size policies.
2) Only adjust the size policies of the widgets, I found that adding stuff in the grid layout starts making things confusing. The stretch factor for the widget's size policy should work fine.
3) Don't be afraid to try different ratios for stretch factors.
I've found that this is one of the things where Qt Designer (Creator) is helpful for puzzling these things out. It's much faster to adjust things in Designer and resize then the run compile cycle. After you have solved the issue there, you can take the properties you have found and put it in your code instead of a edit, compile, run.