QHBoxLayout has incorrect width - qt

Hello :) This is my code (with what I tried in comment). "this" is a class derived from QWidget, and "this" has no size because I want to fit it depending on the size of childs (so in the "paintEvent", I call "adjustSize()") :
QPushButton *button1 = new QPushButton("Hello and good morning");
QPushButton *button2 = new QPushButton("World");
QHBoxLayout *h1 = new QHBoxLayout(this);
QHBoxLayout *h2 = new QHBoxLayout(this);
QVBoxLayout *v = new QVBoxLayout(this);
h1->addWidget(button1);
h2->addWidget(button2);
//h2->setSizeConstraint(QLayout::SetMaximumSize);
//h2->setSizeConstraint(QLayout::SetDefaultConstraint);
//h2->setSizeConstraint(QLayout::SetFixedSize);
//h2->setSizeConstraint(QLayout::SetMinAndMaxSize);
v->addLayout(h1);
v->addLayout(h2);
//v->setSizeConstraint(QLayout::SetDefaultConstraint);
//v->setSizeConstraint(QLayout::SetFixedSize);
//v->setSizeConstraint(QLayout::SetMaximumSize);
//v->setSizeConstraint(QLayout::SetMinAndMaxSize);
//v->setSizeConstraint(QLayout::SetMinimumSize);
//v->setSizeConstraint(QLayout::SetNoConstraint);
QSize s1 = h1->sizeHint();
QSize s2 = h2->sizeHint();
QSize s3 = h1->totalSizeHint();
QSize s4 = h2->totalSizeHint();
QSize s5 = h1->totalMaximumSize();
QSize s6 = h2->totalMaximumSize();
QSize s7 = h1->totalMinimumSize();
QSize s8 = h2->totalMinimumSize();
setLayout(v);
show();
I get this result : Only the button1 is visible. When I put a breakpoint at "setLayout(v)" I see that each QSize of h2 has a size of (0, 0).
My question is : How can I see the button2 (and the button1 of course :) ) ? I don't want to set a min/max size because the button has to fit with its text.
Have a good day !

The layout is set directly to the widget passed as parameter in the constructor of your layout. But, a widget can have only one layout at the same time.
Remove the this parameter and it should work.
QHBoxLayout *h1 = new QHBoxLayout();
QHBoxLayout *h2 = new QHBoxLayout();
QVBoxLayout *v = new QVBoxLayout();

Related

How to move QWidget in QAbstractItemView?

I have a QComboBox, which has many items on it:
combo->addItem("def");
combo->addItem("abc");
Now I would like to add QWidget to one of my item, for example:
QPushButton *button = new QPushButton;
button->setStyleSheet("QPushButton {background:red}");
button->setFixedSize(10,10);
QModelIndex index = combo->model()->index(0,0);
combo->view()->setIndexWidget(index, button);
I set button's size to 10x10 ( of course my QComboBox is bigger ). And I would like to move this button to other place ( picture ).
You can try using layout
QPushButton *button = new QPushButton;
button->setStyleSheet("QPushButton {background:red}");
button->setFixedSize(10,10);
auto widget = new QWidget{this};
auto layout = new QHBoxLayout{widget};
layout->setContentsMargins(0, 0, 0, 0);
layout->addStretch();
layout->addWidget(button);
QModelIndex index = combo->model()->index(0,0);
combo->view()->setIndexWidget(index, widget);

How to avoid hidden QWidget height included in QStackedLayout?

I have this scenario with which I have been struggling for few hours:
I have a main widget, whose layout is set to main_layout, before which 3 layouts are added to the main_layout:
A QVBoxLayout (header_app_layout)
A second QVBoxLayout (header_loader_layout)
A QStackBoxLayout (content_layout)
The QStackBoxLayout (content_layout) has 2 child widgets added to it, of which only 1 is shown:
m_content1_widget (shown widget)
m_content2_widget
My problem is that, content_layout is taking into consideration the heights of the hidden child widgets in the widget: m_content1_widget, because of which the main_widget height is overflowing.
If I change content_layout from QStackedLayout to QVBoxLayout type, it all starts working fine.
So it seems to me that, QStackedLayout is respecting the height of the hidden widgets, which I don't want it to. Any ideas to overcome this ?
Here is the code:
main.cpp
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
main_widget w;
w.setFixedSize(400, 400);
w.show();
return app.exec();
}
main_widget.h
#include <QWidget>
#include <QLabel>
#include <QStackedLayout>
#include <QVBoxLayout>
#include <QPushButton>
class main_widget : public QWidget
{
Q_OBJECT
public:
main_widget();
};
main_widget.cpp
#include "main_widget.h"
main_widget::main_widget()
: QWidget(nullptr)
{
QVBoxLayout *header_app_layout = new QVBoxLayout();
QLabel *header_app_label = new QLabel();
header_app_label->setText(tr("Header"));
header_app_layout->addWidget(header_app_label);
QVBoxLayout* header_loader_layout = new QVBoxLayout();
QLabel* header_loader_label = new QLabel();
header_loader_label->setText(tr("Header Loader"));
header_loader_layout->addWidget(header_loader_label);
QWidget *m_content1_widget = new QWidget();
QVBoxLayout* content1_layout = new QVBoxLayout(m_content1_widget);
QPushButton* content1_button1 = new QPushButton(tr("content1_button1"));
content1_layout->addWidget(content1_button1);
QPushButton* content1_button2 = new QPushButton(tr("content1_button2"));
content1_layout->addWidget(content1_button2);
QPushButton* content1_button3 = new QPushButton(tr("content1_button3"));
content1_layout->addWidget(content1_button3);
content1_button2->hide(); //Hidden for now. But it's height is being included
content1_button3->hide();
QWidget* m_content2_widget = new QWidget();
QVBoxLayout* content2_layout = new QVBoxLayout(m_content2_widget);
QPushButton* content2_button1 = new QPushButton(tr("content2_button1"));
content2_layout->addWidget(content2_button1);
QPushButton* content2_button2 = new QPushButton(tr("content2_button2"));
content2_layout->addWidget(content2_button2);
QPushButton* content2_button3 = new QPushButton(tr("content2_button3"));
content2_layout->addWidget(content2_button3);
content2_button2->hide();
content2_button3->hide();
QStackedLayout* content_layout = new QStackedLayout(); //Doesn't work
//QVBoxLayout *content_layout = new QVBoxLayout(); //Works, but I need it to be of type `QStackedLayout` to show the 2 child widgets conditionally
content_layout->addWidget(m_content1_widget);
content_layout->addWidget(m_content2_widget);
content_layout->setStackingMode(QStackedLayout::StackingMode::StackOne);
content_layout->setCurrentIndex(0);
QVBoxLayout* main_layout = new QVBoxLayout;
main_layout->addLayout(header_app_layout); //Adding a QVBoxLayout
main_layout->addLayout(header_loader_layout); //Adding another QVBoxLayout
main_layout->addSpacing(32);
main_layout->addLayout(content_layout); //Adding the QStackedLayout
this->setLayout(main_layout);
}
I was able to resolve the issue by calling adjustSize on m_content2_widget, which removed the space occupied by the hidden controls inside m_content2_widget.
m_content2_widget->adjustSize();

automatic resize using qgraphicsview with qgraphicsscene and qopenglwidget

I'm trying to use QGraphicsView with QOpenGLWidget in a MainWindow:
Exactly:
My QMainWindow contains a few layouts and widget. Also a QGraphicsView (class graphicsView inherits from QGraphicsView).
In a "second" step i create a QGraphicsScene and add a openglwidget (class OpenGLControl inherits from QOpenGLWidget). In OpenGLControl I only set the backround for testing my application (glClearColor ...).
Now my request, when I change the size of mainWindow, i want to change the size of QGraphicsView, QGraphicsScene and QOpenGLWidget, too. I try a resizeEvent in graphicsView, but it didn't work.
Implementation of mainwindow (.cpp):
#include "mainwindow.h"
#include "openglcontrol.h"
#include "graphicsview.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
createLayout();
createScene();
}
void MainWindow::createLayout()
{
view = new graphicsView;
kosGrid = new QGridLayout;
xKoord = new QLineEdit;
yKoord = new QLineEdit;
zKoord = new QLineEdit;
drawButton = new QPushButton("Draw Point");
clearButton = new QPushButton("Clear");
KoordLabel = new QLabel("Koordinaten");
xLabel = new QLabel("X:");
yLabel = new QLabel("Y: ");
zLabel = new QLabel("Z: ");
controlBox = new QVBoxLayout;
controlBox->addStretch(1);
controlBox->addWidget(KoordLabel);
xhBox = new QHBoxLayout;
xhBox->addWidget(xLabel);
xhBox->addWidget(xKoord);
controlBox->addLayout(xhBox);
yhBox = new QHBoxLayout;
yhBox->addWidget(yLabel);
yhBox->addWidget(yKoord);
controlBox->addLayout(yhBox);
zhBox = new QHBoxLayout;
zhBox->addWidget(zLabel);
zhBox->addWidget(zKoord);
controlBox->addLayout(zhBox);
controlBox->addWidget(drawButton);
controlBox->addWidget(clearButton);
xKoord->setFixedWidth(50);
yKoord->setFixedWidth(50);
zKoord->setFixedWidth(50);
drawButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
xKoord->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
yKoord->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
zKoord->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
hBox = new QHBoxLayout;
hBox->addLayout(controlBox);
hBox->addWidget(view);
mainLayout = new QWidget;
mainLayout->setLayout(hBox);
setCentralWidget(mainLayout);
}
void MainWindow::createScene()
{
scene = new QGraphicsScene(this);
qsurface = new QSurfaceFormat;
qsurface->setRenderableType(QSurfaceFormat::OpenGL);
qsurface->setProfile(QSurfaceFormat::CoreProfile);
qsurface->setVersion(3,3);
oglwidget = new OpenGLControl;
oglwidget->setFormat(*qsurface);
oglwidget->
//oglwidget->resize(10,10);
scene->addWidget(oglwidget);
view->setScene(scene);
}
and my attempt for the resizeEvent:
void graphicsView::resizeEvent(QResizeEvent *event)
{
if(scene())
scene()->setSceneRect(QRect(QPoint(0,0), event->size()));
QGraphicsView::resizeEvent(event);
}
at last a screenshot of the (resized) mainWindow (the QOpenGLWidget (blue background) is smaller than the QGraphicsView)
mainWindow with QOpenGLWidget
Is there a SIGNAL I can use ? Or can anybody help me on another way ?
Thank You

How to extract widgets from QHBoxLayout in Qt

I have a TableWidget into which I add Widgets like this:
QLabel *l = new QLabel("TEST");
QWidget *widget = new QWidget();
QHBoxLayout *hbox = new QHBoxLayout();
hbox->addWidget(l);
hbox->setAlignment(Qt::AlignCenter);
hbox->setContentsMargins(0,0,0,0);
widget->setLayout(hbox);
ui->tableWidget->setCellWidget(0, 0, widget);
When a cell gets double clicked I capture the event and would like to figure out what QLabel it is.
But how do I extract it again or do I even have to?
auto widget = ui->tableWidget->cellWidget(ui->tableWidget->currentRow(), ui->tableWidget->currentColumn()); // if mode is SingleSelection
auto hbox = widget->layout();
auto label = qobject_cast<QLabel *>(hbox->itemAt(0)->widget());

Qt - Making a Splitter Horizontal and Vertical at same time

I have a QGridLayout with a QSplitter on it. In that QSplitter I have two elements with a splitter that lets me move the splitter from left to right. Fine, there it's fine. But then I want to add another splitter but that moves up to down. (I'll explain with an image.)
So it's mostly having 2 splitters, one that moves left-to-right and other that moves up-to-down.
I hope you understand.
QGridLayout *layout = new QGridLayout(this);
QSplitter *splitter = new QSplitter();
text1 = new QPlainTextEdit();
text2 = new QPlainTextEdit();
splitter->addWidget(text1);
splitter->addWidget(text2);
text1->resize(800, this->height());
layout->addWidget(splitter, 1, 0);
browser = new QTextBrowser();
browser->resize(1, 1);
layout->addWidget(browser, 2, 0);
setLayout(layout);
Here i add only 1 splitter, since i don't know how to do the 2nd one.
You should be able to adapt this for your needs easily. The idea is to create a container for the first two elements, then connect the container with the 3rd element all via splitters.
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget wnd;
QTextEdit *editor1 = new QTextEdit;
QTextEdit *editor2 = new QTextEdit;
QTextEdit *editor3 = new QTextEdit;
QSplitter *split1 = new QSplitter;
QSplitter *split2 = new QSplitter;
QVBoxLayout *layout = new QVBoxLayout;
QWidget *container = new QWidget;
QVBoxLayout *container_layout = new QVBoxLayout;
split1->addWidget(editor1);
split1->addWidget(editor2);
container_layout->addWidget(split1);
container->setLayout(container_layout);
split2->setOrientation(Qt::Vertical);
split2->addWidget(container);
split2->addWidget(editor3);
layout->addWidget(split2);
wnd.setLayout(layout);
wnd.show();
return app.exec();
}

Resources