Layouts doesn't work in Qt - c++

i'm having a problem with layouts in Qt. I'm trying to compile this code, with 2 horizontal layouts and a vertical main layout. Each horizontal layout have 3 buttons and both horizontal layout are incorporated in the vertical layout. But after i compile this code, i can only see a small window with just the "Exit" button.
firstline = new QHBoxLayout(this);
secondline = new QHBoxLayout(this);
layout = new QVBoxLayout(this);
eat = new QPushButton("Eat", this);
drink = new QPushButton("Drink", this);
smoke = new QPushButton("Smoke", this);
save = new QPushButton("Save", this);
load = new QPushButton("Load", this);
exit = new QPushButton("Exit", this);
firstline->addWidget(eat);
firstline->addWidget(drink);
firstline->addWidget(smoke);
secondline->addWidget(save);
secondline->addWidget(load);
secondline->addWidget(exit);
layout->addLayout(firstline);
layout->addLayout(secondline);
setLayout(layout);

You are already setting the layout for your dialog through these statements...
firstline = new QHBoxLayout(this);
secondline = new QHBoxLayout(this);
So call their constructors without specifying their parent widget.
firstline = new QHBoxLayout();
secondline = new QHBoxLayout();
This would display your layout as you are expecting.

Related

Why HBoxLayout added in a QVBoxLayout turned out to display horizontally, but not vertically?

I want to make a QLable and a QComboBox display in one line (horizontal, let's name it as h_combination_1), and there are some similar layouts like this (e.g. h_combination_2, h_combination_3, and etc). Then I want to manage this combinations (h_combination_1..3) display vertially. But at last these combinations display horizontally, how strange it is! Could someone help me with this?
Here is the code:
void ThemeWidget::initLayout()
{
[..]
QHBoxLayout* themeLayout = new QHBoxLayout;
QLabel* themeLabel = new QLabel("Theme");
themeLayout->addWidget(themeLabel);
themeLayout->addWidget(cbox_theme);
QHBoxLayout* legendLayout = new QHBoxLayout;
QLabel* legendLabel = new QLabel("Legend");
themeLayout->addWidget(legendLabel);
themeLayout->addWidget(cbox_legend);
QHBoxLayout* animationLayout = new QHBoxLayout;
QLabel* animationLabel = new QLabel("Animation");
themeLayout->addWidget(animationLabel);
themeLayout->addWidget(cbox_animation);
antialiasCheckBox = new QCheckBox("Antialiasing");
[..]
QVBoxLayout* parametersLayout = new QVBoxLayout;
parametersLayout->addLayout(themeLayout);
parametersLayout->addLayout(legendLayout);
parametersLayout->addLayout(animationLayout);
parametersLayout->addWidget(antialiasCheckBox);
QWidget* paramsBox = new QWidget();
paramsBox->setLayout(parametersLayout);
gridLayout = new QGridLayout;
QHBoxLayout* layout = new QHBoxLayout;
layout->addLayout(gridLayout);
layout->addWidget(paramsBox);
this->setLayout(layout);
}
Here is a screenshot:
In the begining, I've just add the layout parametersLayout to layout, without binding it to a QWidget.
For example:
void ThemeWidget::initLayout()
{
[..]
QVBoxLayout* parametersLayout = new QVBoxLayout;
parametersLayout->addLayout(themeLayout);
parametersLayout->addLayout(legendLayout);
parametersLayout->addLayout(animationLayout);
parametersLayout->addWidget(antialiasCheckBox);
gridLayout = new QGridLayout;
QHBoxLayout* layout = new QHBoxLayout;
layout->addLayout(gridLayout);
layout->addWidget(parametersLayout);
this->setLayout(layout);
}
But it turned out just as same as binding parametersLayout to a QWidget.
The layoutItems in parametersLayout should be vertical, but there were not!
So I changed into the method I discribed in the details above, and the results was still the same.

How to manage layout on QDockWidget?

I'm getting started with Qt and I have a project for my school. I want to make an interface that read a database of space-stuff and displays them.
Until now I can display the table in a list, and my actual goal is to show the details of the object when it is double clicked.
To do so I tried to open a second dock whenever the object is double clicked, and tried to make a layout inside the second dock to display properly the details.
The program successfuly open a new dock, but the widget are way too small and all packed in the upper left corner of the dock:
picture of the bug:
I tried to do not use layout but only setWidget with QDockWidget, but it does only display the last widget.
Here is my code for the layout:
dock1 = new QDockWidget(tr("Caractéristiques de l'objet : "), this);
dock1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QVBoxLayout* layout = new QVBoxLayout();
Nom_Objets = new QLineEdit(dock1);
layout->addWidget(Nom_Objets);
//dock1->setWidget(Nom_Objets);
Categorie_Objets = new QLineEdit(dock1);
layout->addWidget(Categorie_Objets);
//dock1->setWidget(Categorie_Objets);
Description_Objets = new QTextEdit(dock1);
layout->addWidget(Description_Objets);
//dock1->setWidget(Description_Objets);
setLayout(layout);
addDockWidget(Qt::RightDockWidgetArea, dock1);
If you want to add several widgets to a QDockWidget then you must use a QWidget as a container:
dock1 = new QDockWidget(tr("Caractéristiques de l'objet : "), this);
dock1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
addDockWidget(Qt::RightDockWidgetArea, dock1);
QWidget* container = new QWidget;
dock1->setWidget(container);
QVBoxLayout* layout = new QVBoxLayout(container);
Nom_Objets = new QLineEdit;
Categorie_Objets = new QLineEdit;
Description_Objets = new QTextEdit;
layout->addWidget(Nom_Objets);
layout->addWidget(Categorie_Objets);
layout->addWidget(Description_Objets);

QT C++ Scroll Issues

I have an issue in locking a widget's contents to a scroll-area.
I think the best way to describe is in the pictures attached.
Picture 'a' is normal operation without a scroll area
Picture 'b' is when I attempt to add a scroll area to the widget.
The scroll- area appears but the text is not contained within.
The scroll-area is its own seperate entity with the content appearing away from it.
This is the code which I have placed in my widget:
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
scrollArea->setVisible(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setWidget(this);
scrollArea->setGeometry(680, 250, 560, 440);
scrollArea->setBackgroundRole(QPalette::Light);
Any ideas?
Picture a :
Picture b :
Here is the call to the custom child widget from the main GUI:
subalerPane = new subalertsPane(mstrWnd);
subalerPane->setObjectName(subalertspane_params._name);
subalerPane->setGeometry(QRect(subalertspane_params._x, subalertspane_params._y, subalertspane_params._w, subalertspane_params._h));
subalerPane->setPixmaps(QPixmap(subalertspane_params._normalImageDm), QPixmap(subalertspane_params._normalImageNm), QPixmap(subalertspane_params._minimisedImageDm), QPixmap(subalertspane_params._minimisedImageNm));
subalerPane->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
subalerPane->setAttribute(Qt::WA_TranslucentBackground);
subalerPane->setState(subalertspane_params._defaultState);
subalerPane->setUIMode(subalertspane_params._defaultUIMode);
subalerPane->setVisible(true);
subalerPane->raise();
Here is the subalertsPane cpp file:
subalertsPane::subalertsPane(QWidget *parent) :QLabel(parent)
{
subalertsPane::state=bsNormal;
subalertsPane::pressable=true;
subalertsPane::uiMode=bdnDay;
connect(this, SIGNAL(clicked()), this, SLOT(slotClicked()));
connect(this, SIGNAL(released()), this, SLOT(slotReleased()));
statbutts[0] = new statusButton(this);
statbutts[1] = new statusButton(this);
statbutts[2] = new statusButton(this);
statbutts[3] = new statusButton(this);
statbutts[4] = new statusButton(this);
statbutts[5] = new statusButton(this);
statbutts[6] = new statusButton(this);
statbutts[7] = new statusButton(this);
statbutts[8] = new statusButton(this);
statbutts[9] = new statusButton(this);
statbutts[10] = new statusButton(this);
for (int i = 0; i < 11; i++)
{
statbutts[i]->fadeIn();
statbutts[i]->setVisible(false);
}
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
scrollArea->setVisible(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setWidget(this);
scrollArea->setGeometry(680, 250, 560, 440);
scrollArea->setBackgroundRole(QPalette::Light);
}
QScrollArea::setWidget() is used for setting a widget inside the scroll area with the the content.
Example: if you want a QLabel with a text inside the scroll area - scrollArea->setWidget(qLabel);
Then add the scroll area to a layout of the view
auto *scrollArea = new QScrollArea(this);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setWidgetResizable(true);
auto *buttonsWidget = new QGroupBox(scrollArea);
scrollArea->setWidget(buttonsWidget);
auto *comboboxesLayout = new QVBoxLayout();
buttonsWidget->setLayout(comboboxesLayout);
mainLayout->addWidget(scrollArea);

Qt layouts, difference between passing and not passing QWidget as parent

I have created a simple QHBoxLayout (horizontal) that is pushed to the bottom of the QVBoxLayout (Vertical) and it contains two buttons. See code:
QWidget* create_ver_and_horizontal_box() {
QWidget* temp = new QWidget();
// Add buttons to the horizontal box
QHBoxLayout* hbox = new QHBoxLayout();
QPushButton *ok = new QPushButton("OK");
QPushButton *cancel = new QPushButton("Cancel");
hbox->addWidget(ok);
hbox->addWidget(cancel);
// Create a vertical box and add the horizontal box to
// the end of it
QVBoxLayout* vbox = new QVBoxLayout();
vbox->addStretch(1);
vbox->addLayout(hbox);
// set the layout and return
temp->setLayout(vbox);
return temp;
}
and the resulting UI is the following.
But when I add the QWidget temp to be the parent of the QHBoxLayout, like so:
// Add buttons to the horizontal box
QHBoxLayout* hbox = new QHBoxLayout(temp);
This is what I get:
I want to understand what is going on here. And in which cases I want the QWidget to be the parent of a layout or any other QWidget(s) and in which cases I don't the containing QWidget to be the parent of the containing QWidgets. For example, I could've added temp to be the parent of the two Push buttons but I didn't. What is the implication of not adding vs adding.
Thanks,
QHBoxLayout* hbox = new QHBoxLayout(temp);
is equivalent to
QHBoxLayout* hbox = new QHBoxLayout();
temp->setLayout(hbox);
I.e. you are making the horizontal layout responsible for temp.
The call to setLayout(vbox) should have generated a runtime warning message, that temp already has a layout, hinting at that.
Since you want the vertical layout to be responsible for that widget, either keep the temp->setLayout(vbox) or pass temp to the constructor of QVBoxLayout.

Items in QHBoxLayout layout overlap

I can't figure out what is wrong with Qt. I am trying to create a simple layout, like this:
+-------+-----------+
| | Label1 |
| Thumb |-----------+
| | Label2 |
| |(multiline)|
+-------+-----------+
And this is the code that does this:
labelInfoName = new QLabel("Sample name", this);
labelInfoDetails = new QLabel("Sample details...", this);
labelInfoDetails->setAlignment(static_cast<Qt::Alignment>(Qt::AlignTop | Qt::AlignLeft));
QVBoxLayout* textInfoLayout = new QVBoxLayout(this);
textInfoLayout->addWidget(labelInfoName);
textInfoLayout->addWidget(labelInfoDetails, 1);
// Create info pane
imgInfoThumbnail = new QLabel(this);
imgInfoThumbnail->setFixedSize(64, 64);
imgInfoThumbnail->setStyleSheet("background: black;");
QHBoxLayout* infoLayout = new QHBoxLayout(this);
infoLayout->addWidget(imgInfoThumbnail);
infoLayout->addLayout(textInfoLayout, 1)
this->setLayout(infoLayout);
And this is a QWidget. This is the code that sets up the layout in a class derived from QWidget. Then I want to display it as a dockable widget, which I do like this from my QMainWindow class:
widget = new Widget(this); // Widget that was set up above
QDockWidget* dockWidget = new QDockWidget("Project", this);
dockWidget->setWidget(widget);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
But this is what I get instead:
I need the widget to be a custom control that I can place anywhere. Previously, it was defined as a QDockWidget, and instead of calling this->setLayout() I was creating a QWidget object, and this worked as expected:
QWidget* widget = new QWidget(this);
widget->setLayout(infoLayout);
this->setWidget(widget);
But the way I've done it now, it puts them on top of each other. What am I doing wrong?
You are creating layout incorrectly.
When you pass parent (widget) to a layout this layout is set automatically as layout to this widget.
Problem is that once layout is set for a widget it can't be changed, I'm pretty sure you are receiving some warning about this.
So just remove this when constructing a layout (at least in first case):
labelInfoName = new QLabel("Sample name", this);
labelInfoDetails = new QLabel("Sample details...", this);
labelInfoDetails->setAlignment(static_cast<Qt::Alignment>(Qt::AlignTop | Qt::AlignLeft));
QVBoxLayout* textInfoLayout = new QVBoxLayout();
textInfoLayout->addWidget(labelInfoName);
textInfoLayout->addWidget(labelInfoDetails, 1);
// Create info pane
imgInfoThumbnail = new QLabel(this);
imgInfoThumbnail->setFixedSize(64, 64);
imgInfoThumbnail->setStyleSheet("background: black;");
QHBoxLayout* infoLayout = new QHBoxLayout(this);
infoLayout->addWidget(imgInfoThumbnail);
infoLayout->addLayout(textInfoLayout, 1)
this->setLayout(infoLayout);