Centering a Label vertically in a horizontal layout - c++

I am having a bit of a problem with centering my QLabel vertically within a QHBoxLayout. The relevant piece of my code is below:
QFrame* topBar = new QFrame();
topBar->setStyleSheet("background-color: #2c3d50;border-bottom: 3px solid #2c92b6;");
topBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
topBar->setFixedHeight(24);
QHBoxLayout* topBarLayout = new QHBoxLayout();
QLabel* label = new QLabel("MSFT");
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
label->setStyleSheet("font-size: 15px;font-weight: bold;border: 0px;");
label->setMinimumHeight(15);
topBarLayout->addWidget(label);
topBar->setLayout(topBarLayout);
topLayout->addWidget(topBar);
My local goal is to have the label vertically centered. What I tried:
Qt::AlignVCenter - had no impact
QSizePolicy::PreferredSize and QSizePolicy::Expanding caused the label to be vertically shrunk without minimumHeight/fixedHeight, where I hoped it to expand freely to the height of the parent
Changing the minimumHeight or adding padding/margin:, which only continue to move the QLabel downwards.
My ultimate goal is to create a bar (that dark blue thing in the photo) of fixed height and variable width, with labels and buttons (e.g. caption, close, maximize etc.) aligned on the both sides, regardless of the bar's width.
Internets say that adding yet another QBoxLayout to center the Label vertically could solve the problem, but I will be adding lots of components to that bar, so this "solution" would be very impractical.
TL;DR: How does one align a Label (or simply its text) vertically within a horizontal layout?

Try to change top/bottom margins of the layout and keep Qt::AlignVCenter:
topBarLayout->setContentsMargins(9,0,9,5);

Related

Setting minimum fixed size QCustomPlot bar graph inside QSplitter

I am using QCustomPlot to plot a bar graph. There are two such bar graphs horizontally arranged inside a QSplitter (which can be dragged). On dragging the splitter horizontally, the bar graphs resize and scale to the point that the axes labels start to overlap. I have a parent QWidget which contains a QScrollArea which ultimately contains the plot. This widget is added to the QSplitter.
QWidget* topLeftParent = new QWidget;
topLeftParent->setLayout(new QVBoxLayout);
QScrollArea *topLeftScrollArea = new QScrollArea(this);
topLeftScrollArea->setWidget(energyGraph->GetPlot());
topLeftScrollArea->setWidgetResizable(true);
topLeftScrollArea->setFrameShape(QFrame::NoFrame);
topLeftParent->layout()->addWidget(topLeftScrollArea);
m_pTopLeftHorizontalSplitter->setMinimumWidth(500);
m_pTopLeftHorizontalSplitter->addWidget(topLeftParent);
Existing Behaviour:
On dragging the splitter horizontally, the bar graphs expand/shrink horizontally till the axes tick labels overlap and ultimately at a very small value of width, the horizontal scrollbar appears, which is useless. Same is the case for resizing the window as well.
Required Behavior
However, I seek a different behavior. I want the bar graphs to be horizontally scrollable without them resizing on dragging the splitter i.e. dragging the splitter left/right should reveal more/less of the graphs, and not resize them
Queries
How do I specify that the bar graph should have a minimum size and expand from that depending on the number of ticks on x-axis?
How do I stop the plot from automatically expanding/shrinking?
What I have tried so far
I have tried setting minimum size for the plot, but it does not work.
I have also tried specifying the stretch factor for the splitter to 0, but that also has no effect i.e. the behavior is auto resizing bar graphs in both the cases with scrollbar appearing too late.
To achieve the required behavior you can use the QTableWidget widget. You need to:
Create a QTableWidget widget with two columns and and one row.
Set the QScrollArea widget as the parent of the QTableWidget widget.
Hide the horizontal and vertical headers. To do so set horizontalHeaderVisible and verticalHeaderVisible to false.
Add QCustomPlot widgets into the table using the setCellWidget(int row, int column, QWidget * widget) method.
This is how it was solved: I just had to call the setWidgetResizable with false for the scroll area and now I have a permanent scrollbar and the custom plot does not resize while dragging the splitter.
Find if you have this line:
ui->my_plot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag);
And edit it to whatever you want, for example just range zoom:
ui->my_plot->setInteractions(QCP::iRangeZoom);

Qt space around QPushButton in QHBoxLayout

I have a QLabel and a QPushButton added to a QHBoxLayout. The QLabel has its margins set to 0 and the layout has margin and content margins set to 0. The label and button have the same background color and the button has border set to none. However, the button still looks with a brighter color than the label and there is some extra space around the button, so it doesn't look like it's "glued" to the label. I want them to look like one big widget.
In Qt, margins describe the space surrounding the layout. In newer versions of Qt, the margins on the top/bottom/left/right can be set individually through setContentsMargins().
The space between widgets in the same layout is described by the spacing property. The spacing has nothing to do with the margins. Try calling hboxLayout->setSpacing(0); This should work.
Some days ago I have coded a widget with similar behavior. To avoid problems with margins and colors I can recommend to use second QPushButton button instead of QLabel and set both buttons to be flat with btn->setFlat(true);

setGeometry on button in group with Qt?

So I am in the works of making my first GUI. So far I have made a groupbox and then made a layout and added buttons widgets to that layout(and then added that layout to the group).
All this works fine but when I then compile it, it fills the whole width of the groupbox and something like "50" in height.
I then tried to use setGeometry on the buttons but this does nothing, I can set a size with setFixedSize() but not a positions, why is this? and how can i set a position on the buttons?
You should try to add horizontal and vertical spacers in your layout to position your widget in a proper place in layout. For instance you can place two horizontal spacers on the left and right side of your button and two vertical spacers at the bottom and top. This way your button always stays at the center of layout with an appropriate size.
If you are using Qt Designer you can find them in the Spacers section and add them to your layout. If not you can use QSpacerItem like:
QSpacerItem *horizontalSpacer;
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout->addItem(horizontalSpacer, 0, 0, 1, 1);

QLabel::setPixmap() and QScrollArea::setWidget()

I've been tracking down a bug that boils down to this - if you show an image label inside a scroll area, the label will not be resized to the image's size if QLabel::setPixmap() is called after QScrollArea::setWidget().
This example illustrates the problem, just replace /path/to/some/image.png with some real image on your computer:
QScrollArea *scrollArea = new QScrollArea;
QLabel *label = new QLabel(scrollArea);
scrollArea->setWidget(label);
label->setPixmap(QPixmap("/path/to/some/image.png"));
scrollArea->show();
If you swap the lines to call setPixmap() before setWidget(), the label will be properly resized.
Why does this happen, and how can I force the label to resize properly?
Set your scroll area's widgetResizable property to true:
scrollArea->setWidgetResizable(true);

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.