How to move QWidget in QAbstractItemView? - qt

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

Related

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

Getting QTableWidgetItem out of cellWidget()'s QCheckBox

I'm storing QCheckBox in QTableWidget, in following way:
QCheckBox *checkBox = new QCheckBox();
QWidget *widget = new QWidget();
QHBoxLayout *layout = new QHBoxLayout(widget);
layout->addWidget(checkBox);
layout->setAlignment(Qt::AlignCenter);
layout->setContentsMargins(0,0,0,0);
widget->setLayout(layout);
tableWidget->setCellWidget(row, 2, widget);
Then, I catch stateChanged() of the checkBox:
connect( checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkBoxStateChanged(int)) );
void MainWindow::checkBoxStateChanged(int)
{
QCheckBox * box = qobject_cast< QCheckBox * >( sender() );
if( !box ) {
return;
}
}
Now, I can get to QTableWidget – it is box->parent()->parent()->parent(). Object before that, i.e. box->parent()->parent(), is qt_scrollarea_viewport (that's objectName()). I've searched children of the "viewport", and there's 16 QWidgets – the number of rows in my table. However, their children are only QHBoxLayout and QCheckBox. There apparently is no reference to QTableWidgetItem – it looks like if I were in some parallel object hierarchy, and QTableWidgetItem is in other hierarchy. Is that true? How to get the item?
See this question: How to work with signals from QTableWidget cell with cellWidget set
Adapted to you case:
void MainWindow::checkBoxStateChanged(int)
{
QCheckBox * box = qobject_cast< QCheckBox * >( sender() );
if (box)
{
int row = box->property("row").toInt();
int column = box->property("column").toInt();
QTableWidgetItem* item = tableWidget->item(row, column);
}
}

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

Set widget background color

I use QCheckBox in QTableWidgetCell
QWidget *widget = new QWidget();
QCheckBox *checkBox = new QCheckBox();
QHBoxLayout *layout = new QHBoxLayout(widget);
layout->addWidget(checkBox);
layout->setAlignment(Qt::AlignCenter);
layout->setContentsMargins(0, 0, 0, 0);
widget->setLayout(layout);
table->setCellWidget(0, 0, widget);
How can I change cell background?
The code:
widget->setStyleSheet("background-color: red");
works fine but you need to set the style for every container widget you add to your table:
So in order to see the change you need the following code:
QWidget *widget = new QWidget();
widget->setStyleSheet("background-color: red");
QCheckBox *checkBox = new QCheckBox();
QHBoxLayout *layout = new QHBoxLayout(widget);
layout->addWidget(checkBox);
layout->setAlignment(Qt::AlignCenter);
layout->setContentsMargins(0, 0, 0, 0);
widget->setLayout(layout);
QWidget *widget2 = new QWidget();
widget2->setStyleSheet("background-color: red");
QCheckBox *checkBox2 = new QCheckBox();
QHBoxLayout *layout2 = new QHBoxLayout(widget2);
layout2->addWidget(checkBox2);
layout2->setAlignment(Qt::AlignCenter);
layout2->setContentsMargins(0, 0, 0, 0);
widget2->setLayout(layout);
ui->tableWidget->setCellWidget(0, 0, widget);
ui->tableWidget->setCellWidget(0, 1, widget2);
And the result will be:
You should try this:
checkBox->setStyleSheet("background-color: red;");
If you want to specify it more generally, write the classtype in the CSS to indicate which class in the hierarchy should handle the flag. This could look something like this then:
QWidget { background-color: red; }
If you want to change cell background, not a widget, use setBackground() method:
QCheckBox *checkBox = new QCheckBox("example");
QWidget *widget = new QWidget();
QHBoxLayout *layout = new QHBoxLayout(widget);
layout->addWidget(checkBox);
layout->setAlignment(Qt::AlignCenter);
layout->setContentsMargins(0, 0, 0, 0);
widget->setLayout(layout);
ui->tableWidget_2->setCellWidget(0,0,widget);
ui->tableWidget_2->item(0, 0)->setBackground(Qt::red);//this line should be
In this case all your cell will be red (without white lines around checkbox).

Qt widgets not placed correctly

I've subclassed QWidget and defined constructor this way:
LoupingWidget::LoupingWidget(QWidget *parent): QWidget(parent)
{
QGroupBox *topGroupBox = new QGroupBox(this);
QGraphicsView *xRGBPlot = new QGraphicsView(this);
QGraphicsView *yRGBPlot = new QGraphicsView(this);
QGraphicsView *loupe = new QGraphicsView(this);
QSlider *slider = new QSlider(this);
QGridLayout *boxGLayout = new QGridLayout;
boxGLayout->addWidget(xRGBPlot, 0, 0);
boxGLayout->addWidget(slider, 0, 1);
boxGLayout->addWidget(loupe, 1, 0);
boxGLayout->addWidget(yRGBPlot, 1, 1);
topGroupBox->setLayout(boxGLayout);
}
Next, I am trying to add it in a QDialog:
Window::Window(QWidget *parent): QDialog(parent)
{
LoupingWidget *firstLoupindWidget = new LoupingWidget(this);
LoupingWidget *secondLoupindWidget = new LoupingWidget(this);
// QGraphicsView *mainPicture = new QGraphicsView(this);
QGridLayout *gridLayout = new QGridLayout;
// gridLayout->addWidget(mainPicture, 0, 0);
gridLayout->addWidget(firstLoupindWidget, 1, 0);
gridLayout->addWidget(secondLoupindWidget, 1, 1);
setLayout(gridLayout);
}
When this two lines are commented out, two widgets are placed horizontally.
And that's good, but when I uncomment lines with another QGraphicsViews, it fills entire window.
What am I doing wrong?
LoupingWidget doesn't have a layout, so when it's added to another layout, layout can't resize it according to its contents. You need to create another layout (e.g. QGridLayout) in LoupingWidget constructor, add topGroupBox to the layout and set the layout as LoupingWidget's layout.

Resources