3
votes

I want to create a resizable window that contains some icons that resize according to window. I created a window and placed the icons in a grid layout, it worked as i wanted so far.

But the problem is that when I shrink the window to tiny size, icons are too small and can't recognize at all. So I set the minimum size of the icons and it seemed to solve the first problem.

Now, the problem is that icons are overlap when I shrink the window and it looks ugly.

I tried using spacer, widget margin, spacing of layout and minimumRowHeight property.

But Qt seems the window size is higher priority than widget's minimum size or margin or other.

They all shrink and still no space at all between widgets.

I can solve this problem with minimum size of window. However, it will take several attempts to determine the best looking minimum size.

So my question is:

  1. I wonder if there is a margin(or spacing) between widgets in layout that never shrink. If there is, I just place my icons in a generous window size and set a margin that doesn't shrink, so the minimum size of window can be determined it self.

  2. If not, what is best way to make what I want? is that minimum size of window? If then, how do I determine the best minimum size?

Any advice or documentation would be highly appreciated.

Add:

  1. This is what I want. I set the minimum height of window to 380px.

  1. If I'm not set the minimum height, the icons are overlap as above

  1. I changed height several times to determine the height of the image at 1, if the height is not enough, the icons too close as shown

Here's some code:

verticalLayout = new QVBoxLayout(widget); // window layout

labelTime = new QLabel(widget);
verticalLayout->addWidget(labelTime);

gridLayout1 = new QGridLayout(); // grid layout at top
gridLayout1->setSpacing(15);
labelIcon1 = new QLabel(widget);
labelIcon1 ->setMinimumSize(QSize(40, 40));
labelIcon1 ->setPixmap(QPixmap(path));
gridLayout1->addWidget(labelIcon1, 0, 0, 1, 1);

... // create icons and add to gridlayout1

verticalLayout->addLayout(gridLayout1);

line = new QFrame(widget);  // just line.
verticalLayout->addWidget(line); // add to vertical layout, not grid layout.

... // create grid layout, icons at bottom and add it to vertical layout, same as top

Structure looks like this: QLabel, QGridLayout, Line, QGridLayout2 are placed in a vertical layout.

-------------vertical layout
[   text   ]
-------------grid layout
[icon][text]
[icon][text]
-------------grid layout
[   line   ]
-------------grid layout 2
[icon][text]
[icon][text]
[icon][text]
-------------grid layout 2
-------------vertical layout
1
So setting the spacing property doesn't help?Nikos C.
I think your English is great, and your questions are clear. :DJennifer S
@NikosC. Yes, I tried. But resize the window to tiny size, property is ignored and icons are overlap. If I set the minimum height of window to be slightly smaller than the best height, the property is ignored and the icons are too close.Dean Lee
@JenniferS Thanks :)Dean Lee

1 Answers

2
votes

The problem is that you have set a minimum size for the QLabel but not for the QPixmap, since you want the icons to change the size based on the size of the window then you can set the scaledContents property of QLabel to true.

On the other hand I would recommend using a QGridLayout for all elements so the alignment of the icons would be maintained, in the following part there is an example:

#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    QGridLayout *layout = new QGridLayout(&w);

    QLabel *title = new QLabel("2020-01-01 00:00:00");
    title->setAlignment(Qt::AlignHCenter);
    layout->addWidget(title, 0, 0, 1, 2);

    QLabel *icon1 = new QLabel;
    icon1->setAlignment(Qt::AlignCenter);
    icon1->setPixmap(QPixmap(":/icon1.png"));
    icon1->setMinimumSize(40, 40);
    icon1->setScaledContents(true);
    layout->addWidget(icon1, 1, 0);
    QLabel *text1 = new QLabel("Disconnected");
    text1->setAlignment(Qt::AlignCenter);
    layout->addWidget(text1, 1, 1);

    QLabel *icon2 = new QLabel;
    icon2->setAlignment(Qt::AlignCenter);
    icon2->setPixmap(QPixmap(":/icon2.png"));
    icon2->setMinimumSize(40, 40);
    icon2->setScaledContents(true);
    layout->addWidget(icon2, 2, 0);
    QLabel *text2 = new QLabel("HDD 0%");
    text2->setAlignment(Qt::AlignCenter);
    layout->addWidget(text2, 2, 1);

    QFrame *line = new QFrame;
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    layout->addWidget(line, 3, 0, 1, 2);

    QLabel *icon3 = new QLabel;
    icon3->setAlignment(Qt::AlignCenter);
    icon3->setPixmap(QPixmap(":/icon3.png"));
    icon3->setMinimumSize(40, 40);
    icon3->setScaledContents(true);
    layout->addWidget(icon3, 4, 0);
    QLabel *text3 = new QLabel("0");
    text3->setAlignment(Qt::AlignCenter);
    layout->addWidget(text3, 4, 1);

    QLabel *icon4 = new QLabel;
    icon4->setAlignment(Qt::AlignCenter);
    icon4->setPixmap(QPixmap(":/icon4.png"));
    icon4->setMinimumSize(40, 40);
    icon4->setScaledContents(true);
    layout->addWidget(icon4, 5, 0);
    QLabel *text4 = new QLabel("0 ( 0% )");
    text4->setAlignment(Qt::AlignCenter);
    layout->addWidget(text4, 5, 1);

    QLabel *icon5 = new QLabel;
    icon5->setAlignment(Qt::AlignCenter);
    icon5->setPixmap(QPixmap(":/icon5.png"));
    icon5->setMinimumSize(40, 40);
    icon5->setScaledContents(true);
    layout->addWidget(icon5, 6, 0);
    QLabel *text5 = new QLabel("0 ( 0% )");
    text5->setAlignment(Qt::AlignCenter);
    layout->addWidget(text5, 6, 1);

    w.show();
    return a.exec();
}

enter image description here

If you want to modify the space between rows, columns or both then you must use layout->setVerticalSpacing(spacing), layout->setHorizontalSpacing(spacing) and layout->setSpacing(spacing), respectively.