Making a QWidget fill 100 of its parent - qt

Im trying to create a Qt application where I want a QWidget to fill 100% of the main-window, and ocasionally I want two widgets side by side. I've setup a layout on the main-window and tried to write:
QMainWindow::centralWidget()->layout()->setContentsMargins(0, 0, 0, 0);
Which worked, but had a weird 1px border to the left and the top. I then tried: QMainWindow::centralWidget()->layout()->setSpacing(0); in combination with with setContentsMargins(0, 0, 0, 0) but it still has that 1px border. I tried to set the position to (1, 1) but that just moved the line to the bottom and right, so it seems like the window is being oversized by 1px.
Does anyone know the answer to why this is happening?
(The widget is red and the background is black)

It is not easy to answer without working example or more info. It may be caused by OS rendering system, math-alignment (how is created the rectangle?), scalling/dpi etc.

Related

Strange behavior of margins for Qt controls

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.

Gradient created in a style sheet look different from those created via a QBrush?

I am using Qt 4.8.5 with a tree view and I would like to color the background of some items with a gradient depending on what the user is doing. One possibility is that the user moves the mouse over a tree item. The only way to set the background to a gradient in this case is to define a style sheet like that and to set it as the tree views style sheet:
QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 rgb(255, 255, 255), stop: 1 rgb (0, 255, 255);
border: 1px solid rgb (0, 255, 255); }
This works.
There are situations where I would like to mark tree items the same way, even when the mouse is not placed over this tree item (there is a 3D view and some items of the 3D view correspondent to tree items – I would like to highlight the tree view items, when the user points on those items in the 3D view).
This is also possible. I the data(…) method of the document tree model, I return a brush that I have created like this:
QLinearGradient gradient(0, 0, 0, 1);
gradient.setColorAt(0, QColor(255, 255, 255));
gradient.setColorAt(1, QColor(0, 255, 255));
QBrush brush(gradient);
This also works. The only problem is, that the gradient defined with the brush is much different from the gradient defined with the style sheet, even though the numbers are the same (actually in this example the complete background is white – but when I play with the numbers I realize that it is indeed a gradient, but not the one I had expected).
Could someone explain me the reason?
I thought that this could be the case because the QLinearGradient interprets the x1, x2, y1, y2 value as pixels. Does the style sheet interpret these values as relative values? I have played around with the coordinate mode of the gradient, but this did not help.
How can I make both gradients look the same? Or should I get rid of those style sheets and define everything with QBrush’s?
Another question: my impression is, that those Qt style-sheets are not really well-thought-out. Is this just because I don't know yet how to use them or is this really the case?
I will try to make the problem clearer by adding some screen shots (I should have done that immediately). The coordinate mode of the following QLinearGradient instances has been set to QGradient::ObjectBoundingMode:
This is the tree item with the gradient defined by the style sheet:
This is the tree item with the gradient defined by the QBrush with a QLinearGradient(0, 0, 0, 1):
This is the tree item with the gradient defined by the QBrush with a QLinearGradient(0, 0, 1, 1):
My problem is: neither of the QBrush/QLinearGradient combinations looks like the gradient defined by the style sheet. Is anyone out there who has managed to create a QBrush/QLinearGradient that looks like the style sheet gradient?
Sadly, you can NOT change the CoordinateMode of your gradient in Qt CSS qlineargradient(...).
It is always QGradient::ObjectBoundingMode, see the code.
You can change the CoordinateMode of your gradient. Set it to QGradient::ObjectBoundingMode if you want it to be relative to the bounding rectangle, like it is in the stylesheets.
From the stylesheet reference docs: Gradients are specified in Object Bounding Mode.
One thing that is wrong in your code, is the usage of QGradient::setColorAt. You are using 255 as the position parameter, even though the acceptable range is between 0 and 1. You should be receiving a warning message for this.
The QGradient::ObjectBoundingMode option does not work as expected for item view items. I was able to accomplish a similar task in a QTableView by using the default mode and pixel coordinates. The coordinates are relative to the item's visual rectangle. In my case, I have access to the view and was able to use QAbstractItemView::visualRect().
if (role == Qt::BackgroundRole)
{
QColor c = ...
QRectF r = table()->visualRect(mi);
QLinearGradient g(0,0, 0,r.height());
g.setColorAt(0, c.lighter(200));
g.setColorAt(1, c);
return QBrush(g);
}

Expanding a Qt Layout : how to put a widget on the right side and the let the other widget to fully fill the left?

I want to put a widget on the right side of a QHBoxLayout, and the other spaces should expand the left side. I've set the widget's SizePolicy to Expanding, but it's not valid. Anyone could offer some help? Thanks.
Code is here:
QHBoxLayout* tmplayout = new QHBoxLayout(this);
tmplayout->setContentsMargins(0, 0, 0, 0);
lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
tmplayout->addWidget(lineEdit, 0, Qt::AlignRight);
tmplayout->addWidget(pushButton, 0, Qt::AlignRight);
lineEdit should expand.
Try changing:
tmplayout->addWidget(lineEdit, 0, Qt::AlignRight);
tmplayout->addWidget(pushButton, 0, Qt::AlignRight);
To:
tmplayout->addWidget(lineEdit);
tmplayout->addWidget(pushButton);
When dealing with simple layouts like this, there is no need to specify alignments or stretch factors explicitly.
If you want to force pushButton to specific size, you can use setMinimumSize, setMaximumSize, and setFixedSize
Best regards
For the widgets you want to be on the left and expand, try to simply add them before the ones on the right, and add a 1 for their stretch factor. For example,
tmplayout->addWidget(exampleWidget, 1);
Then, you could simply add the widgets you want to be on the right side after the ones on the left, using just:
tmplayout->addWidget(lineEdit);
tmplayout->addWidget(pushbutton);
This will automatically give them a stretch factor of 0.
Since the stretch factor of exampleWidget in this example is 1 which is higher than the default 0, exampleWidget will expand; and, since you add it before the others, it will be on the left.
I am not sure if I understand your problem correctly, but maybe you need to look into QSpacerItem. If that is not helpful, maybe you can make a rough mock-up in Qt-Creator and post the screen shots (one example showing approx. what you have, one example showing what you want)
Try fixed or minimum size policies. Even you may want to fix the maximum width.

image used as image map highlights onclick

I am having an image that is being used as an image map.Image map highlights as gray onclick.I want no highlightening.This doesnot happens on safari on mac.However, this happens only on ipad simulator/device.
use CSS on your images
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
it will set the highlight color to fully transparent (alpha 0) black making it not display if you will set alpha to 1.0 on the other hand you will make the highlight to fully cover the clickable area.
refer to Safari CSS Reference for more details

Splitting an image in GWT results in unwanted white space

I am using GWT 2.03 and am have an image that I want to place partially in an area with a background and partially above a background. I am using a FlexTable to try to accomplish this and have used GIMP to cut the image into two sections. I am trying to load the top part of the image into row 0 and the bottom part of the image into row 1. I set the alignment of the top image to ALIGN_BOTTOM but there is a bit of space at the bottom of cell and so the two parts of the picture don't touch.
Here is an image showing what I am talking about. I set the background of the cell to be yellow show where the cell boundaries are. The bottom image and background are rendering correctly.
![alt text][1]
[1]: http://www. freeimagehosting. net/uploads/f02462d659.png
Here is the relevant code snippet:
FlexTable table = new FlexTable();
table.setCellSpacing(0);
table.setCellPadding(0);
table.setBorderWidth(0);
FlexCellFormatter formatter = table.getFlexCellFormatter();
table.setWidget(0, 0, topImage);
formatter.setStyleName(0, 0, "topImageStyle");
formatter.setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_BOTTOM);
table.setWidget(1, 0, bottomImage);
formatter.setStyleName(1, 0, "bottomImageStyle");
How can I get rid of that space between my image and the cell boundary?
This is caused by the Standards rendering mode (see this article for a thorough explanation).
A quick fix (which should be applicable for this case) is to set your image slices to have the display: block style.
PS: It probably doesn't matter at this size (2x1) but Grid should be used when the size of the table is constant/known beforehand - it just offers better performance than FlexTable.
GWT has a class called DecoratorPanel, which targets this use case. See the JavaDoc for details on how to use it.
I have some suggestion for you:
I'm not sure, if this work for FlexTable, but try setCellPadding(0) or setCellSpacing(0)
Try addStyleName or setStylePrimary instead setStyleName
Try to set the style to the image and not to the formatter
Try also formatter.setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_BOTTOM) with formatter.setStyleName(1, 0, HasVerticalAlignment.ALIGN_TOP).
Firebug can help you to find, what you need to change to fix the problem. If you post peace of code (DOM), we can try to help you.

Resources