Реакция на изменение виджета в ячейке QTableWidget
Есть таблица в которую добавлен виджет QCheckBox.
Как реализовать, чтобы при установке галочки в QCheckBox появлялась возможность редактировать соседнюю ячейку, а без галочки - нет?
Методы QTableWidget::itemChanged, cellChanged не работают, так как QCheckBox создается на слое и добавляется в ячейку.
Часть кода с созданием QCheckBox в ячейке:
for (int i = 0; i < (ui->am->value()); i++)
{
QTableWidgetItem *header_ = new QTableWidgetItem();
header_->setText(QString::number(ui->addr->value()+i));
ui->tableWidget->setVerticalHeaderItem(i,header_);
/**
* Создание виджета для чекбокса.
* Оцентровка в ячейках.
*/
QWidget *checkboxWidget = new QWidget();
QCheckBox *checkBox = new QCheckBox();
QHBoxLayout *layoutOfCheckBox = new QHBoxLayout(checkboxWidget);
layoutOfCheckBox->addWidget(checkBox);
layoutOfCheckBox->setAlignment(Qt::AlignCenter);
layoutOfCheckBox->setContentsMargins(0,0,0,0);
ui->tableWidget->setCellWidget(i,1,checkboxWidget);
ui->tableWidget->setItem(i,0, new QTableWidgetItem(""));
}
Способ с нажатием на кнопку работает, но необходимо, чтобы реакция была сразу при изменении QCheckBox.
Реализация через кнопку:
void coils::on_readButton_clicked()
{
vector <bool> buffer; //вектор для хранения считанных данных из койлов
for (int i=0; i<ui->tableWidget->rowCount();i++)
for (int j=0; j<ui->tableWidget->columnCount()-1;j++)
{
QWidget *check = ui->tableWidget->cellWidget(i,1); //получение состояния CheckBox
QCheckBox *check_box = qobject_cast <QCheckBox*> (check->layout()->itemAt(0)->widget()); //получение виджета из слоя и каст в CheckBox
if (check_box->isChecked()) //проверка состояния CheckBox
{
mb.modbus_read_coils(ui->addr->value()+i,1,&buffer);//передача адреса, количества и указателя на вектор, где хранить
ui->tableWidget->setItem(i,j, new QTableWidgetItem(QString::number(buffer[0])));
buffer.clear();
}
else
{
ui->tableWidget->setItem(i,j, new QTableWidgetItem(""));
ui->tableWidget->item(i,j)->setFlags(Qt::NoItemFlags);
}
}
}
Таблица имеет следующий вид:
Ответы (1 шт):
Автор решения: Alexander Chernin
→ Ссылка
По идее вот так:
QCheckBox *checkBox = new QCheckBox();
...
QTableWidgetItem* item = new QTableWidgetItem();
ui->tableWidget->setItem(i, 0, item);
// Обратите внимание на захват [&, item=item]
connect(checkBox, &QCheckBox::stateChanged, [&, item=item](int state){
item->setFlags(state == Qt::Checked ?
Qt::ItemIsEditable | Qt::ItemIsEnabled :
Qt::NoItemFlags);
});
Хотя, при прочих равных, я бы наследовал QCheckBox:
class MyCheckBox: public QCheckBox {
Q_OBJECT
public:
MyCheckBox(QTableWidgetItem* item, QWidget* parent = nullptr):
QCheckBox(parent),
item(item) {
}
protected:
void nextCheckState() override {
QAbstractButton::nextCheckState();
this->item->setFlags(
checkState() == Qt::Checked ?
Qt::ItemIsEditable | Qt::ItemIsEnabled :
Qt::NoItemFlags
);
}
private:
QTableWidgetItem* item;
}
И тогда все становится предельно скучным:
QTableWidgetItem* item = new QTableWidgetItem();
MyCheckBox *checkBox = new MyCheckBox(item);
QWidget *checkboxWidget = new QWidget();
QHBoxLayout *layoutOfCheckBox = new QHBoxLayout(checkboxWidget);
layoutOfCheckBox->addWidget(checkBox);
layoutOfCheckBox->setAlignment(Qt::AlignCenter);
layoutOfCheckBox->setContentsMargins(0,0,0,0);
ui->tableWidget->setCellWidget(i, 1, checkboxWidget);
ui->tableWidget->setItem(i, 0, item);
