QDialog not auto-reducing to fit it contents - c++

When using a QDialog with dynamic contents, the size of the window may get bigger to better fit the contents.
However, in my case, I'd also like it to auto-reduce it size if the contents become smaller (In my case, a form that may differ regarding the choices made).
How can I reach this behaviour?
Thanks
It can be reproduced by adding two buttons:
void MainWindow::on_pushButton_2_clicked()
{
for (int i=0; i<12; i++) {
QPushButton *button = new QPushButton("Blha");
buttons.push_back(button);
ui->zone->addWidget(button);
}
adjustSize();
}
void MainWindow::on_pushButton_clicked()
{
for (int i=0; i<10; i++)
if (buttons.size()) {
QPushButton *button = buttons.back();
buttons.pop_back();
ui->zone->removeWidget(button);
delete button;
}
adjustSize();
}
If you create the 12 buttons like above and then destroy 10 of them, the size of the window will be really big

Actually, I eventually solved this out by wrapping my contents in a widget (like the centralWidget of a MainWindow) and calling adjustSize() on my widget

Related

How to properly delete QWidget from layout QT?

I know, that I can delete QWidget from QLayout so:
QLayoutItem*item = wlay->takeAt(0);
wlay->removeItem(item);
delete item;
delete w;
However, without deleting QWidget(delete w), the widget will be on the screen. However, I cant delete the widget, so the widget will be on the screen. How to delete the widget from screen after removing it from layout?
For example, I have so code:
class QTest: public QWidget{
Q_OBJECT
QVBoxLayout* wlay;
QPushButton* b;
public:
QTest(){
wlay = new QVBoxLayout();
b = new QPushButton("click");
for(int i = 0; i < 20; i++)
wlay->addWidget(new QLabel( "TEST" + QString::number(i)));
wlay->addWidget(b);
this->setLayout(wlay);
connect(b, &QPushButton::clicked, this, &QTest::doit);
}
public slots:
void doit();
};
void QTest::doit(){
//Removing all QLabel from Layout
for(int i =0; i < 20; i++){
QLayoutItem*item = wlay->takeAt(0);
wlay->removeItem(item);
delete item;
}
}
After removing QLabels from layout, labels are showed on screen. How to remove them from main Widget(without deleting them)?
It seems the function you're looking for is QWidget::hide().
Moreover, once you've called QLayout::takeAt(), you don't have to call QLayout::removeItem() afterwards since the former already removes the item as mentioned in the documentation.
You can see QLayout::takeAt() as a shorthand for QLayout::itemAt() + QLayout::removeItem().

Widgets with FixedSize change their size at will

I have a QGridLayout inside a center widget, which contains a supposedly fixed-sized widget (referred to as inner widget) that also has a QGridLayout filled with buttons. Inner widget's size is determined by how many buttons are there in the grid, and is supposed to be an exact fit (no spacing between the buttons, FixedSize policy applied in buttons' constructor), and all buttons have their sizes and policies set in the constructor. Now, if I don't put inner widget into a layout of any kind, it works just fine, I get nice square buttons. But if I put inner widget into a grid layout, all buttons suddenly change their sizes, and widget also doesn't seem like keeping its size. Why?
Edit: MyButtonTable:
MyButtonTable::MyButtonTable(QWidget *parent) : QWidget(parent), array()
{
size_x = 2;
size_y = 2;
QGridLayout* layout = new QGridLayout();
for(size_t x = 0; x < size_x; x++) {
this->array.push_back(std::vector<MyRightClickButton*>());
}
for(size_t x = 0; x < size_x; x++) {
for(size_t y = 0; y < size_y; y++) {
this->array[x].push_back(new button_t());
QObject::connect(array[x][y], SIGNAL(rightClicked()), this, SLOT(internalRightClick()));
QObject::connect(array[x][y], SIGNAL(clicked()), this, SLOT(internalClick()));
layout->addWidget(array[x][y], x, y);
}
}
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
this->setLayout(layout);
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
this->setMinimumSize(QSize(0,0));
this->resize(QSize(10*size_y,10*size_x));
}
MyRightClickButton(QWidget *parent = 0):QPushButton(parent) {
marked = false;
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
this->setMinimumSize(QSize(0,0));
this->resize(QSize(10,10));
}
A layout manager is used to arrange child widgets in them. The arrangement designates each layout manager. Layout managers adjust the size of their child widgets based on the resize policies. Even if you are setting a fixed size for a child widget, using resize() or setGeometry(), they will be resized by the layout manager, if you did not set the resize policy of the child widget.
For example
widget->setFixedSize (100, 100);
widget->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
This is how it should be done.

How to make a 2d Array in QT?

Hi my question is simple, I just asked in the QT Forums but nobody answer to me.
I just wanted to make a 2D array of a QLabel, can somebody help me, All I read about it, they use a dynamic vector, something like this:
<QVector <Data_Type>>
I can't use that (My project don't have to use that yet, crap specifications I know), so I have to use a 2D like in C++ or C.
EDIT: I have the 2D Array but dont know how to show it, All I have is this, and don't give me errors:
QWidget *mainWidget = new QWidget;
QLabel **maze;
maze= new QLabel*[x];
for (int i = 0; i < x; i++) {
maze[i]= new QLabel[y];
}
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
maze[i][j].setPixmap(test);
maze[i][j].move(i*60,j*60);
}
}
mainWidget->show();
setCentralWidget(mainWidget);
Now I just want to show the images, once I run the project, no images appear, is the Widget thing right? How to show in the Main Window? I need a 2D Widget too?
Thanks for your time.
Assuming that the x and y are number of rows and columns, correspondingly, you can simply do this trick:
[..]
QGridLayout *grid = new QGridLayout;
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
QLabel *label = new QLabel(this);
label->setPixmap("Path_Of_The_Image");
grid.addWidget(label, i, j);
}
}
[..]

Spacing between widgets in QHBoxLayout

I'm trying to create a GUI with QtCreator. For this GUI, I need to display several images with different sizes next to each other. These images should be touching each other.
I use a QWidget with a QHBoxLayout, where I add the labels (with different sizes) containing the images.
According to related questions, I should use setSpacing and setContentsMargin to remove these spaces, but that won't work; I tried several times.
Here's the code:
QWidget *widget = new QWidget(ui->tagcloud);
QHBoxLayout * l = new QHBoxLayout(widget);
ui->tagcloud->setWidget(widget);
for(int i=0;i<list.size();++i)
{
QLabel *lab = new QLabel;
QPixmap pic((list[i].imgPath).c_str()); //This fetches the image
int sizeChange = 50 + (2*list[i].percent); //Calculates the size of the image
lab->setFixedSize(QSize(sizeChange, sizeChange));
lab->setPixmap(pic);
lab->setScaledContents(true);
l->addWidget(lab);
l->setSpacing(0);
}
However, when I run this, the spacing remains the same (i.e. definitely not zero).
If I add more labels to the layout, the spacing seems to get smaller.
Can anyone explain or help me? Thanks!
Setting spacing to 0 and adding stretch before and after works for me :
l->addStretch();
for(int i = 0; i < list.size(); ++i)
{
QLabel *lab = new QLabel;
QPixmap pic((list[i].imgPath).c_str()); //This fetches the image
int sizeChange = 50 + (2*list[i].percent); //Calculates the size of the image
lab->setFixedSize(QSize(sizeChange, sizeChange));
lab->setPixmap(pic);
lab->setScaledContents(true);
l->addWidget(lab);
}
l->addStretch();
l->setSpacing(0);
Also this works I think
l->setSizeConstraint(QLayout::SetMaximumSize);

QScrollArea with multiple QWidgets only shows empty box

I am trying to create a widget that would display some information. Each information would be a QWidget that contains multiple QLabel with text (the information). My idea is to put multiple (array of these) into a QScrollArea so that the user can view them scrolling up and down. The following code:
InfoWidget::InfoWidget(QWidget* parent) : QWidget(parent){
widgets = new QVector<MarkerInfoWidget*>();
csv_data = 0;
csv_velocity = 0;
labels = 0;
infoWidgetLayout = new QVBoxLayout(this);
setLayout(infoWidgetLayout);
scrollArea = new QScrollArea(this);
scrollWidgetLayout = new QVBoxLayout(scrollArea);
scrollArea->setLayout(scrollWidgetLayout);
infoWidgetLayout->addWidget(scrollArea);
//Test
QString name = "TEST";
for(int i=0; i<10; i++){
MarkerInfoWidget* markerWidget = new MarkerInfoWidget(name, scrollArea);
scrollWidgetLayout->addWidget(markerWidget);
widgets->append(markerWidget);
}
}
Both MarkerInfoWidget and InfoWidget extends QWidget. What I am getting is simply a box that has very small text:
If I drag it out and re-size it, it display correctly:
What I have noticed is that if I re-size it too small, it does not generate scrolls. What do I need to fix this?
I guess changing:
scrollArea->setLayout(scrollWidgetLayout);
to sth like:
QFrame* frame = new QFrame(scrollArea);
frame->setLayout(scrollWidgetLayout);
scrollArea->setWidget(frame);
As far as i know you have to put widget into QScrollableArea to make it really scrollable. Setting its layout is probably not the thing you want to do.