Реакция на изменение виджета в ячейке 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);
→ Ссылка