How to paint image inside of the entire QScrollArea? - c++

Steps to reproduce using Qt Designer:
1- Add a "Grid Layout"
2- Right click in the MainWindow background and
Lay out -> Lay out in Grid
3- Add a "Scroll Area"
4- Add a "Frame"
5- Right click in the "Scroll Area" and
Lay out -> Lay out in Grid
6- Add a "Label" into the "Frame" and right click it
and Lay out -> Lay out in Grid
7- Add a "border-image" in the Label StyleSheet
Result:
Looks like its padding 10px in each side.
Would like to ask how i could make the image added into the QLabel to occupy the entire QScrollArea, filling these empty areas around the image where are marked with a X.
If possible using stylesheet.

Widget's geometry is not the problem. If your widget is inside layout, then you do not need to care about geometry at all because it is automatically calculated by the layout. You only may need to care about the geometry of the whole window, but not child widgets.
The blank space around your widget is determined by layout's contents margins. Set the contents margins for the layout - set them all to zero. See the picture. If you have multiple layers of layout, you may want to set zero margins for all of them. It depends on your usecase.
You can also set the margins in code using yourLayout->setContentsMargins(0, 0, 0, 0);.

Related

Add widget next to qscrollbar

How do I place a widget next to a QScrollbar like here seen:
I use a QScrollArea and overwrite the Horizontal-QScrollBar. First I thought, I could use the paintEvent to draw a text like the "100 %" next to the bar. But I can only overwrite the existing painting.
Now I think, the only opportunity would be to implement the hole QScorllBarPrivate from the source code... anyone any idea?
The main idea is to create an overlay obscuring default horizontal scroll bar and displaing your own bottom line instead.
Create a widget representing the bottom line, i.e. a widget with labels displaying some information and a horizontal QScrollBar, all together put in a hbox layout.
Put this widget in the scroll area without adding it to a layout by making QScrollArea direct parent widget of this widget.
Use move() and resize() on the bottom line widget to position it properly on initialization. Also resize and reposition it on scroll area resize (you can use event filters or inheritance to get to resize events).
Make sure that scroll area's horizontalScrollBarPolicy is Qt::ScrollBarAlwaysOn so that scroll area's internal layout always keeps space enough for bottom line widget to fit in.
Also make sure that bottom line widget has the same height as default scroll bar. It should be easy as long as you remove spacing and margins in the hbox layout and labels (or other widgets) don't require more vertical space than a scroll bar.
Use horizontalScrollBar() to get scroll area's internal QScrollBar and syncronize it with your own bar. QScrollBar has rangeChanged() and valueChanged() signals so you can connect to them and update your bar properly. When user changes value of your scroll bar and triggers its valueChanged() signal, you should set the same value for the internal scrollbar. You can protect from infinite recursion in there by using a flag that indicates that this is your own change.

Area for detachable QDialogs within QGridLayout

I have a QMainWindow with a QGridLayout of various widgets that looks like the following:
I will have various little input dialogs that come up at different times, and I want them to appear in certain cell of the layout (bright cyan area below purple tab widget in picture). They would show up in this cell by default but should be detachable and able to be moved around as desired (just like a regular, stray QDialog).
What would be the best way to go about this?
I tried using a QDockWidget and just adding it right into the grid layout, but it seems I cannot un-dock it and move it around, even with a call to setFeatures that should allow this freedom.
The addDockWidget function allows the desired movement, but this won't let me incorporate the dock area within the grid; it just puts the dock widget on, e.g., one side of the entire main window.

How to make a QLabel fill the child QWidget?

I have QWidget, used Lay Out in a Grid, then a QLabel, but there are some spaces between the QWidget and QLabel. How can I make them the same size and not break the layout?
I'm using this from UI editor.
When you select the widget, in the UI editor's property pane you should see the options for the layout that belongs to it (the options have a red background, and they're usually at the bottom of the list). Amongst the options are ones for setting the margin in pixels between widgets in the layout, if you set it to 0 it should solve your problem.

Anchoring a QGraphicsView to the corner of the screen

I have a QGraphicsView that renders my game. This view fills the entire screen at all times. In the top right I have another QGraphicsView which I'm using as a mini-map; it sits over the game view. I want this mini-map to be anchored to the top right of the screen, always maintaining its size. This code almost works, except that the left side of the mini-map never changes (which is to be expected).
void MainWindow::resizeEvent(QResizeEvent *event)
{
mainWindow->graphicsView->resize(event->size().width(), event->size().height());
QRect newRect(mainWindow->miniMapGraphicsView->geometry());
newRect.setRight(event->size().width() - 20);
mainWindow->miniMapGraphicsView->setGeometry(newRect);
}
How can I do this?
When you want to position widgets in a certain way, layouts are usually the best way to do it.
Add a QFormLayout to your graphicsView and set its layoutDirection to Qt::RightToLeft. Then add your miniMapGraphicsView to the layout. Editing the properties of the mini map, set its horizontal and vertical sizePolicy to Fixed and set its minimumSize and maximumSize to the dimensions you would like it to be.
An alternative would be to use a QGridLayout and use horizontal and vertical spacers to push the mini map to any corner of the view.
NOTE: Layouts have margins set by default so if you want your widgets to align snugly at the edges, zero them out.

Qt splitter layout resize behaviour using Qt Designer

I have an issue with size in my view made in Qt with drag and drop.
Let me start with an image to help me explain
This is the mainwindow for my form.
What happens is:
We have 4 tab widgets. the left tab widget has a horizontal splitter to the 2 mid widgets.
The 2 mid widgets have a vertical splitter, and a horizontal splitter on the left and right side.
The right widget has a vertical splitter on its left hand.
So all views are connected using splitters.
Lastly the mainform sticks every thing together in a resizable way using horizontal layout.
The problem is, the width of the leftmost and rightmost widgets are fixed (in designer).
I want them to be smaller in width. Something similar to:
You can see the widgets are resized. I was able to do this running the application, and manually adjusting the splitters. Is there a way in QtDesigner to do this? I tried playing with policies. I didn't really get any further however. Does this indicate a lack of knowledge of my part about policies? Perhaps layouts in general?
What options should I use to achieve the desired layout using QtDesigner. I want to avoid using code.
Hope I will be able to solve this soon. It must be overlooking something simple..
You can play with the "Horizontal Stretch" and "Vertical Stretch" properties to change the position of the split.
For example with both the vertical stretch of the top central QTabWidget and the horizontal stretch of the central QSplitter at 1 and all the other values kept at 0, you'll get the result you want.
When you have multiple non-zero stretch values, the result of the ratio (e.g.: vertical strech at 2 and 1 for the 2 central QTabWidgets => 2/3 and 1/3) is not visible in the designer but seems to be working when you run the application.
PS: You can also achieve the same result with tabbified QDockWidgets but the dock tabbification is not possible through the designer only.
I set start position that:
QList<int> list= ui->splitter->sizes();
list.replace(0,this->height()/0.3);
list.replace(1,this->height()/0.7);
ui->splitter->setSizes(list);
and remember to minimum size child widget