How to extract widgets from QHBoxLayout in Qt - 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());

Related

Problem adding QPushButtons to my app. When I run the code, only the last button is placed in my window. The previous 8 are being overwritten

This is what I have so far. When I run the app, the last button in the array gets placed which means that the previous 8 are being stepped on.
QWidget *qwid = new QWidget(this);
QGridLayout *gl = new QGridLayout(qwid);
qwid->setLayout(gl);
QTabWidget *qtab = new QTabWidget();
qtab->addTab(qwid, "name");
QStringList buttonLbls({"button1", "button2", "button3:});
QHBoxLayout *hbox = new QHBoxLayout(qwid);
QPushButton *btnCount[3];
for(int i=0; i<3; i++)
{
btnCount[i] = new QPushButton(buttonsLbls[i], qwid);
hbox->addWidget(btnCount[i]);
qwid->setLayout(hbox);
}
You are setting two different layouts for the main widget. Remove the first (gl). Try to set the layout for the main widget and then add buttons:
qwid->setLayout(hbox);
for(int i=0; i<3; i++)
{
btnCount[i] = new QPushButton(buttonsLbls[i], qwid);
hbox->addWidget(btnCount[i]);
}
First you need to decide whether you want to have your buttons in a grid or not.
If you go with gridlayout then you can just add your widgets with the QGridLayout::addWidget and pass the correct row and column where the widget should go inside the grid. You won't need the separate horizontal layout in that case. Finally you set the gridlayout as the layout of your parent widget (qwid).
QWidget* qwid = new QWidget(this);
QGridLayout* gridLayout = new QGridLayout();
QStringList buttonLabels({"button1", "button2", "button3", "button4"});
QHash<QString, QPushButton*> buttons; // For storing button pointer for easy access
int columns = 2;
for (int n = 0; n < buttonLabels.size(); n++)
{
int column = n % columns;
int row = n / columns;
const QString& buttonLabel = buttonLabels.at(n);
QPushButton* button = new QPushButton(buttonLabel);
buttons[buttonLabel] = button;
gridLayout->addWidget(button, row, column);
}
qwid->setLayout(gridLayout);
An alternative is to use combination of horizontal and vertical layout where you create horizontal layout for each row (in a loop), add your widgets to the horizontal layout. Then add each horizontal layout inside a single vertical layout with addLayout function. Finally you set the vertical layout as the layout of your parent widget (qwid).
QWidget* qwid = new QWidget(this);
QVBoxLayout* verticalLayout = new QVBoxLayout();
QStringList buttonLabels({"button1", "button2", "button3", "button4"});
QHash<QString, QPushButton*> buttons; // For storing button pointer for easy access
int columns = 2;
int rows = columns / buttonLabels.size();
int index = 0;
for (int row = 0; row < rows; row++)
{
QHBoxLayout* rowLayout = new QHBoxLayout()
for (int col = 0; col < columns; col++)
{
const QString& buttonLabel = buttonLabels.at(index);
QPushButton* button = new QPushButton(buttonLabel);
buttons[buttonLabel] = button;
rowLayout->addWidget(button);
index++;
}
verticalLayout->addLayout(rowLayout);
}
qwid->setLayout(verticalLayout);
Another alternative is to just use the horizontal (or vertical) layout only and just add the widgets there and set the layout as the layout of your parent widget (qwid).
QWidget* qwid = new QWidget(this);
QHBoxLayout* horizontalLayout = new QHBoxLayout();
QStringList buttonLabels({"button1", "button2", "button3", "button4"});
QList<QPushButton*> buttons; // For storing button pointer for easy access
for (const QString& buttonLabel : buttonLabels)
{
QPushButton* button = new QPushButton(buttonLabel);
buttons << button;
horizontalLayout->addWidget(button);
}
qwid->setLayout(horizontalLayout);
It depends on what you actually want to do with your widgets.

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

QHBoxLayout has incorrect width

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

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

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