Qt - how to customizing QTableWidget's checkbox - c++

I've tried to set some style for check box for Qt. I've already knew that QtTableWidget has QCheckbox. but problem is I have no idea how to set style for checkbox of QtTableWidget.
QTableWidgetItem *checkBoxItem = new QTableWidgetItem();
checkBoxItem->setCheckState(Qt::Unchecked);
table->setItem(row, column, checkBoxItem);
When I use setStyleSheet for checkBox :
checkBoxItem->setStyleSheet("...");
I have an error:
'class QTableWidgetItem' has no member named 'setStyleSheet'
Edited: I want to do some operation with checkBox. Here is complete code for first QTableWidgetItem:
for (int i = 0; i < 4; ++i)
m_tableWidget->setRowHeight(i, 3 * em);
QTableWidgetItem *item1 = new QTableWidgetItem(tr("Show Message Preview"));
if (CGlobalZone::m_showMsgPreview)
item1->setCheckState(Qt::Checked);
else
item1->setCheckState(Qt::Unchecked);
item1->setFlags(Qt::ItemIsEnabled);
m_tableWidget->setItem(0, 0, item1);

You can style the indicators with QAbstractItemView::indicator { ... } (eg QTableView::indicator:checked, QTableView::indicator:unchecked etc).
You can't apply style directly to the QTableItemWidget, but you can put a stylesheet on the QTableWidget itself or a parent of it.

Assuming, you already have a table widget with at least one column and at least one row:
QCheckBox *cb = new QCheckBox(tr("Check me"));
cb->setStyleSheet("background-color: rgb(0, 85, 0);");
tableWidget->setCellWidget(0, 0, cb);

Related

qt treewidget widget item QCheckBox alignment

I have a QTreeWidget where I insert different widgets (QDoubleSpinBox,QSpinBox,QCheckBox...)
QTreeWidget *t = ui->treeWidget;
QTreeWidgetItem *item = new QTreeWidgetItem();
int c = 0;
QDoubleSpinBox *dspb = new QDoubleSpinBox();
t->setItemWidget(item, c++, dspb);
QSpinBox *spb = new QSpinBox();
t->setItemWidget(item, c++, spb);
QCheckBox *cb = new QCheckBox();
t->setItemWidget(item, c++, cb);
t->addTopLevelItem(item);
However, the cb widget looks wired since the checkbox is aligned to the left. I would like to see it aligned in the center.
Q: How can I change the checkbox to appear in the middle of the TreeWidget cell?
I need to be able to access the cb item again later. Currently, I use the following code:
QTreeWidgetItem *itm = t->topLevelItem(0);
bool checked = qobject_cast<QCheckBox *>(t->itemWidget(itm,c++))->checkState() == Qt::Checked;
If I need to do some workaround to get the central alignment going, how can I access the cb object then?
Found it:
cb->setStyleSheet("margin-left:50%; margin-right:50%;");
works!

Radio Button never appears

With the following code to create radio buttons in a group box I get no results. A bit of background : in my display every objects has multiple variants and the user must choose which one to display (or all). What update/refresh command did I miss, or what is wrong ?
for(int i = 0; i < MAX_NUM_VARIANTS+1; i++)
{
m_variantButtons[i] = new QRadioButton();
m_variantButtons[i]->setText(QString::number(i));
m_variantButtons[i]->setObjectName(QString("m_pbDisplayVariant%1").arg(i));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(true);
m_variantButtons[i]->setSizePolicy(sizePolicy);
((QGridLayout*)(ui.m_groupBoxVariants->layout()))->addWidget(m_variantButtons[i], 1, i);
((QGridLayout*)(ui.m_groupBoxVariants->layout()))->update();
connect(m_variantButtons[i], SIGNAL(clicked(bool)), this, SLOT(updateDisplaySettings()));
m_variantButtons[i]->setVisible(true);
}
((QWidget*)(ui.m_groupBoxVariants))->updateGeometry();

Qt table widget, button to delete row

I have a QTableWidget and for all rows I set a setCellWidget at one column to a button.
I would like to connect this button to a function that delets this row.
I tried this code, which does not work, because if I simply click my button I do not set the current row to the row of the button.
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
QPushButton *b = new QPushButton("delete",this);
ui->tableWidget->setCellWidget(ui->tableWidget->rowCount()-1,0,b);
connect(d,SIGNAL(clicked(bool)),this,SLOT(deleteThisLine()));
...
void MainWindow::deleteThisLine()
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
How can I connect my button to a function in a way that the function knows which button (at which row) was pressed?
To remove the row we must first get the row, if we are inserting widgets inside the cells the currentRow() method will not return the appropriate row, in many cases it will return the row of the last cell without widget that has been selected.
For that reason you must opt for another solution, for this case we will use the indexAt() method of QTableWidget, but for this we need to know the position in pixels of the cell. when one adds a widget to a cell, this cell will be the parent of the widget, so we can access from the button to the cell using the parent() method, and then get the position of the cell with respect to the QTableWidget and use it in indexAt(). To access the button we will use the sender().
When the current cell is removed the focus is lost, a possible solution is to place the focus again in another cell.
void MainWindow::deleteThisLine()
{
//sender(): QPushButton
QWidget *w = qobject_cast<QWidget *>(sender()->parent());
if(w){
int row = ui->tableWidget->indexAt(w->pos()).row();
ui->tableWidget->removeRow(row);
ui->tableWidget->setCurrentCell(0, 0);
}
}
Use this connection way to connect signal to a slot:
connect(ui->btnDelete, &QPushButton::clicked, this,&MainWindow::deleteRow);
And delete for example a row on call function:
void MainWindow::deleteRow()
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
Create a custom class, where you pass the created push button object and the row index. From your custom push button class, handle the push button press event and emit a custom signal (it will carry the index number) handled from the object where your custom pushbutton is created. Some related code are below, to give you a hint:
.h
class mypushbutton {
explicit mypushbutton(QObject *parent = 0, QPushButton *pushbutton = 0, int index = 0);
signal:
void deleteRow(int index);
}
.cpp
mypushbutton() {
connect(pushbutton, SIGNAL(clicked(bool)), this, SLOT(actionButtonClick(bool)));
}
actionbuttonclicked() { emit deleteRow(index);}

QCheckbox name access

I generate checkboxes as follows:
foreach(QString filt, types){
QCheckBox *checkbox = new QCheckBox(filt, this);
checkbox->setChecked(true);
vbox->addWidget(checkbox);
}
I need to get access to these checkboxes by name but they are all called the same?
I need to read the text they display.
How can I go about this?
Is it possible to run a for loop and attach the value of i onto the end of the checkbox. So in effect, the checkbox would be called checkbox[0], checkbox [1], etc?
EDIT:
I've changed the code to the following:
for(int i=0; i<types.count(); ++i)
{
QString filt = types[i];
*checkboxCount = *checkboxCount + 1;
QCheckBox *typecheckbox[i] = new QCheckBox(filt, this);
typecheckbox[i]->setChecked(true);
vbox->addWidget(typecheckbox[i]);
}
I thought this was a way to dynamically name the checkboxes so I can loop through them to get the text value from them.
I'm getting the error 'variable-sized object may not be initialized' on this line QCheckBox *typecheckbox[i] = new QCheckBox(filt, this);
Any ideas to a solution/ alternate approach?
If you want to access the checkboxes later, you can just use the find children method as follows:
QStringList myStringList;
QList<QCheckBox *> list = vbox->findChildren<QCheckBox *>();
foreach (QCheckBox *checkBox, list) {
if (checkBox->isChecked())
myStringList.append(checkBox->text());
}

QComboBox - set selected item based on the item's data

What would be the best way of selecting an item in a QT combo box out of a predefined list of enum based unique values.
In the past I have become accustomed to .NET's style of selection where the item can be selected by setting the selected property to the item's value you wish to select:
cboExample.SelectedValue = 2;
Is there anyway to do this with QT based on the item's data, if the data is a C++ enumeration?
You lookup the value of the data with findData() and then use setCurrentIndex()
QComboBox* combo = new QComboBox;
combo->addItem("100",100.0); // 2nd parameter can be any Qt type
combo->addItem .....
float value=100.0;
int index = combo->findData(value);
if ( index != -1 ) { // -1 for not found
combo->setCurrentIndex(index);
}
You can also have a look at the method findText(const QString & text) from QComboBox; it returns the index of the element which contains the given text, (-1 if not found).
The advantage of using this method is that you don't need to set the second parameter when you add an item.
Here is a little example :
/* Create the comboBox */
QComboBox *_comboBox = new QComboBox;
/* Create the ComboBox elements list (here we use QString) */
QList<QString> stringsList;
stringsList.append("Text1");
stringsList.append("Text3");
stringsList.append("Text4");
stringsList.append("Text2");
stringsList.append("Text5");
/* Populate the comboBox */
_comboBox->addItems(stringsList);
/* Create the label */
QLabel *label = new QLabel;
/* Search for "Text2" text */
int index = _comboBox->findText("Text2");
if( index == -1 )
label->setText("Text2 not found !");
else
label->setText(QString("Text2's index is ")
.append(QString::number(_comboBox->findText("Text2"))));
/* setup layout */
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(_comboBox);
layout->addWidget(label);
If you know the text in the combo box that you want to select, just use the setCurrentText() method to select that item.
ui->comboBox->setCurrentText("choice 2");
From the Qt 5.7 documentation
The setter setCurrentText() simply calls setEditText() if the combo
box is editable. Otherwise, if there is a matching text in the list,
currentIndex is set to the corresponding index.
So as long as the combo box is not editable, the text specified in the function call will be selected in the combo box.
Reference: http://doc.qt.io/qt-5/qcombobox.html#currentText-prop