QLabel::setPixmap() and QScrollArea::setWidget() - c++

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);

Related

Centering a Label vertically in a horizontal layout

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);

qTableView select row -> display image

What I want to achieve:
Whenever I select a row in my qTableView I want to display an image in sort of a "popup" way.
I'm not sure how to go about this. I mean I can display an image in an already present qLabel, but how can I show a qLabel in it's own "window" and destroy this window immediately if no row/another row is selected?
What I have so far:
QLabel *test = new QLabel(this);
test->setPixmap(QPixmap::fromImage(photo));
test->setBaseSize(photo.width(), photo.height());
test->show();
But this only creates a very small label in the left upper corner of the window. How can I get this to be a given size and at position with an offset of the current window?
You set parent to your label, so label appears on parent. Remove parent and label will be shown as separate window.
QLabel *test = new QLabel;
But of course in this case there is memory leak risk. So set attribute to label.
test->setAttribute(Qt::WA_DeleteOnClose);
With this line, when you close your label, it will be immediately destroyed. But I think you should not recreate label to show images. You can show or hide and set new pixmap to one label. If label visible (isVisible() method) set new image, if it is not visible, set new image too and show it. Use clicked() signal of QTableView to catch selection of row/columns.
Use move(), resize() or setGeometry to set different parameters of label.
You should implemented like:
Declared in header :QPixmap *pixH and QLabel * header;
header = new QLabel(this);
pixH = QPixmap(":/images/header.png");
header->setPixmap(pixH);
header->setGeometry(0,0,320,30);
header->setAlignment(Qt::AlignHCenter);

Qt: display an image (QLabel) inside a QScrollArea

I am trying to display an image inside a QScrollArea located on the QMainWindow.
I want a fixed size for the image display, and scroll bars to appear if the loaded image is bigger than the QScrollArea. My problem is that when I load an image which is bigger than the QScrollArea, the image appears cut (which is ok) but no scroll bars appear on the UI.
Taking into account various recommandations from other stackoverflow questions, here is the generated code from the Qt designer:
mImageScrollArea = new QScrollArea(centralWidget);
mImageScrollArea->setObjectName(QString::fromUtf8("mImageScrollArea"));
mImageScrollArea->setGeometry(QRect(440, 0, 400, 700));
mImageScrollArea->setWidgetResizable(false);
scrollAreaWidgetContents = new QWidget();
scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
scrollAreaWidgetContents->setGeometry(QRect(0, 0, 398, 698));
mLabel = new QLabel(scrollAreaWidgetContents);
mLabel->setObjectName(QString::fromUtf8("mLabel"));
mLabel->setGeometry(QRect(0, 0, 400, 700));
QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(mLabel->sizePolicy().hasHeightForWidth());
mLabel->setSizePolicy(sizePolicy);
mLabel->setScaledContents(true);
mImageScrollArea->setWidget(scrollAreaWidgetContents);
When an image is loaded, I display it in the label as follow:
QPixmap wPixmap = QPixmap::fromImage(mImage);
ui.mLabel->resize(wPixmap.size());
ui.mLabel->setPixmap(wPixmap);
ui.mLabel->show();
Why aren't any scrollbars showing if the image I load is bigger than the QScrollArea ?
It would be more helpful if you provide UI file content instead of generated C++ code. Anyway, it seems that scrollAreaWidgetContents doesn't have a layout. You need to add a grid layout to it in Qt Designer. After you do this, you will not need to resize label or scrollAreaWidgetContents manually. They will be resized automatically. Calling show on label is not required either, it will be visible by default (unless you have hid it).

Reserving Space for QScrollArea

I am using a QScrollArea with a custom QWidget. The problem I am facing is that whenever the scrollbar appears, it leads to shifting of elements in the widget. So, I want to reserve some space, so when the scrollbar appears or disappears, the widget is not affected. How can I achieve this?
scrollArea->setWidgetResizable(false);
I encountered this problem and just solved it(might not completely).
I set a fixed width for scroll widget and QScrollArea, and set QScrollArea Horizontal SizePolicy fixed, and hide HorizontalScrollBar.
Sample code
QWidget *pWidget = new QWidget(this);
pWidget->setFixedWidth(500);
pWidget->setLayout(...)
QScrollArea *pScrollArea = new QScrollArea();
// Same with widget
pScrollArea->setFixedWidth(500);
pScrollArea->setWidget(pWidget);
pScrollArea->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
// Needed.
pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
I also find a Bugreport: QTBUG-2347
QScrollArea: a new scroll policy that reserves space for the scroll bar, and it is closed. But I don't know whether the bug is fixed and what's the solution.

resize problem in scroll area

Hello everyone, here is my code:
myplot *p = new myplot(gao.structpayloadgraph,
gao1.structpayloadgraph,
gao.structcol-2, "payload");
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setWidgetResizable(false);
p->resize(ui->scrollArea->size().width(), ui->scrollArea->size().height());
ui->scrollArea->setWidget(p);
I want p to take up the full available space of the scrollbar area and fit itself. However, the appearance looks 'squeezed' even though I called the resize function. What should I do to achieve the desired effect?
You have to treat the scroll area content widget as a normal QWidget. If you want automatic resize and you must use layouts in Qt. Try the following :
QVBoxLayout layout = new QVBoxLayout( ui->scrollAreaContent);
layout->setMargin(0);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
ui->scrollAreaContent->setLayout( layout);
layout->addWidget(p);
NOTE: ui->scrollAreaContent is a guess, but I think you are using ui files and default content widget is named like that ...
Go to the top right of the QT creator designer screen (Object, Class), right click on the QScrollArea row and select the "Lay Out" menu item, choose a layout (eg vertical or horizontal layout), make sure that your QWidget has a minimum or above size policy. Your scroll widget should now resize with the layout.