在QTableWidget中获取QCheckBox的单元格位置

时间:2015-08-26 05:08:22

标签: c++ qt

我有一个QTableWidget,在不同的列上有不同类型的单元格小部件,有多个列显示复选框。

我想将QCheckBox的stateChanged信号连接到我的一个插槽,以便我可以在我的模型中相应地设置数据。

问题是当用户更改QCheckBox状态时,QTableWidget的当前行不一定会改变。

所以我考虑继承QCheckBox并添加用于保存行和列信息的变量。这是一个好方法吗?当我使用UI元素存储数据时,有什么问题(如果有的话)。

5 个答案:

答案 0 :(得分:1)

这只是我想到的第一个想法。 我将所有的QCheckBox连接到同一个插槽(通过它们循环或在创建的那一刻)然后当插槽被执行时,我将得到它的调用者,它将是QCheckBox,我将得到它的父节点,它将是它的单元格&# 39; s in。

答案 1 :(得分:1)

我会在不增加额外课程的情况下这样做,而是将小部件的行和列存储在地图中:

class YourWidgetWithTable
{
public:
    void foo()
    {
        //when you add cell widgets, do something like this:
        QCheckBox * b = new QCheckBox();
        tableWidget->setCellWidget(row, col, b);
        _widgetCells[b] = QPoint(row, col);
        connect(b, &QCheckBox::stateChanged, this, &YourWidgetWithTable::checkboxStateChanged);
        //if for whatever reason you are removing a checkbox from the table, don't forget to remove it from the map as well.
    }

public slots:
    void checkboxStateChanged(int)
    {
        //in your slot, you can now get the row and col like so:
        QCheckBox * box = dynamic_cast<QCheckBox*>(sender());
        QPoint rowAndColumn = _widgetCells[box];
    }

private:
    QMap<QCheckBox*, QPoint> _widgetCells; //QPoint for storing the row and column
}

当然,您可以在不使用dynamic_cast的情况下使用QObject*指针执行相同操作。

答案 2 :(得分:1)

如果您坚持使用setCellWidget并且使用C ++ 11而不是使用lambda表达式进行连接。这样就可以了:

void MainWindow::setupCheckboxes() {
     for (int i=1; i<=tableWidget->rowCount(); ++i) {
         QCheckBox *checkbox = new QCheckBox();
         ... // setup checkbox
         tableWidget->setCellWidget(i, kSomeColumnIndex, checkbox);
         connect(checkbox, &QAbstractButton::toggled, [this, i](bool checked) {
              this->stateOfRowHasChanged(i, checked);
         });
     }
}

void MainWindow::stateOfRowHasChanged(int row, bool checked) {
    // update item model
    QTableWidgetItem *item = tableWidget->item(row, kSomeColumnIndex);
    item->setData(Qt::CheckStateRole, checked?Qt::Checked:Qt::Unchecked);
     ... 
}

如果您不喜欢lambdas,请将复选框连接到此插槽:

void MainWindow::checkboxStateHasChenged(bool checked) {
     QCheckBox *checkbox = qobject_cast<QCheckBox *>(sender());
     if (checkbox) {
         QTableWidgetItem *item = tableWidget->itemAt(tableWidget->mapFrom(checkbox, QPos()));
         if (item) {
             item->setData(Qt::CheckStateRole, checked?Qt::Checked:Qt::Unchecked);
             ...
         }
     }
}

答案 3 :(得分:0)

你做的事情非常糟糕。你没有显示代码所以很难说出什么是错误的(我只是怀疑)。

无论如何这是MVC模式。因此,如果您想观察状态变化,您必须观察数据模型的变化。您应该连接到dataChanged(还有其他更方便的信号QTableWidget::cellChanged)。数据可以model()或更多。

使用数据模型更重要的是,您可以在表格视图中设置检查默认复选框(您不必手动添加它们)。

代码示例:

QTableWidgetItem *item = new QTableWidgetItem(tr("Somthing"));
item->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemNeverHasChildren);
tableWidget->setItem(row, column, item); // or add or whatever to add this item to widget and its model

connect(tableWidget->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), 
        this, SLOT(dataWasChanged(QModelIndex,QModelIndex,QVector<int>)));
// or
connect(tableWidget, SIGNAL(cellChanged(int, int)),
        this, SLOT(cellWasChanged(int, int)));

答案 4 :(得分:0)

QPoint pos = tableWidget->mapFromGlobal(QCursor::pos());
QTableWidgetItem* item = tableWidget->item(tableWidget->indexAt(pos).row() - 1 , 0);

获得该项目后,您将获得该职位。

相关问题