Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 获取QTableWidget中QCheckBox的单元格位置_C++_Qt - Fatal编程技术网

C++ 获取QTableWidget中QCheckBox的单元格位置

C++ 获取QTableWidget中QCheckBox的单元格位置,c++,qt,C++,Qt,我有一个QTableWidget,在不同的列中有不同类型的单元格widget,有多个列显示复选框。 我想将QCheckBox的状态更改信号与我的一个插槽连接,以便在我的模型中相应地设置数据。 问题是,当用户更改QCheckBox状态时,QTableWidget的当前行不一定会更改。因此,我正在考虑继承QCheckBox并添加用于保存行和列信息的变量。这是一个好方法吗?当我使用UI元素来存储数据时,有什么问题(如果有的话)。这只是我想到的第一个想法。 我会将我所有的QCheckBox连接到同一个插

我有一个QTableWidget,在不同的列中有不同类型的单元格widget,有多个列显示复选框。 我想将QCheckBox的状态更改信号与我的一个插槽连接,以便在我的模型中相应地设置数据。
问题是,当用户更改QCheckBox状态时,QTableWidget的当前行不一定会更改。因此,我正在考虑继承QCheckBox并添加用于保存行和列信息的变量。这是一个好方法吗?当我使用UI元素来存储数据时,有什么问题(如果有的话)。

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

我不需要创建额外的类,而是将小部件的行和列存储在映射中:

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
}
将YourWidgetWithTable分类
{
公众:
void foo()
{
//添加单元格小部件时,请执行以下操作:
QCheckBox*b=新的QCheckBox();
tableWidget->setCellWidget(行、列、b);
_widgetCells[b]=QPoint(行,列);
连接(b,&QCheckBox::stateChanged,this,&YourWidgetWithTable::checkboxStateChanged);
//如果出于任何原因要从表中删除复选框,也不要忘记将其从映射中删除。
}
公众时段:
无效checkboxStateChanged(int)
{
//在插槽中,您现在可以获得如下所示的行和列:
QCheckBox*box=dynamic_cast(sender());
QPoint rowAndColumn=_widgetCells[box];
}
私人:
QMap _widgetCells;//QPoint用于存储行和列
}

当然,您可以使用
QObject*
指针在不使用
dynamic\u cast
的情况下执行同样的操作。

您正在做一些非常错误的事情。你没有显示代码,所以很难说到底是什么错了(我只是怀疑)

无论如何,这是MVC模式。所以,如果你想观察状态的变化,你必须观察数据模型的变化。您应该连接到do(还有其他更方便的信号)。数据由一个或多个用户提供

使用数据模型更重要的是,您可以在表视图中设置默认复选框(无需手动添加)

代码示例:

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)));
QTableWidgetItem*item=新的QTableWidgetItem(tr(“Somthing”);
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
tableWidget->setItem(行、列、项);//或add或其他任何将此项添加到小部件及其模型的操作
连接(tableWidget->model(),信号(dataChanged(QModelIndex,QModelIndex,QVector)),
这个插槽(dataWasChanged(QModelIndex,QModelIndex,QVector));
//或
连接(tableWidget,信号(cellChanged(int,int)),
这个插槽(cellWasChanged(int,int));

如果您坚持使用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);
     ... 
}
void主窗口::设置复选框(){
对于(int i=1;irowCount();++i){
QCheckBox*复选框=新的QCheckBox();
…//设置复选框
tableWidget->setCellWidget(i,kSomeColumnIndex,复选框);
连接(复选框,&QAbstractButton::切换,[this,i](布尔选中){
此->状态已更改(i,选中);
});
}
}
void main window::stateOfRowHasChanged(int行,bool选中){
//更新项目模型
QTableWidgetItem*item=tableWidget->item(行,kSomeColumnIndex);
item->setData(Qt::CheckStateRole,选中?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);
             ...
         }
     }
}
void主窗口::checkboxStateHasChenged(bool选中){
QCheckBox*复选框=qobject_cast(sender());
如果(复选框){
QTableWidgetItem*item=tableWidget->itemAt(tableWidget->mapFrom(复选框,QPos());
如果(项目){
item->setData(Qt::CheckStateRole,选中?Qt::checked:Qt::Unchecked);
...
}
}
}

一旦您获得了项目,您就获得了位置。

如何将此复选框添加到表格小部件?你用什么?我怀疑不是这样,您正在使用
QTableWidget
,因为您没有仔细阅读文档。检查我的答案,并用更多细节更新您的问题。我将把数据源传递给tablewidget,并用wtablewidget中数据源的值填充复选框。
QPoint pos = tableWidget->mapFromGlobal(QCursor::pos());
QTableWidgetItem* item = tableWidget->item(tableWidget->indexAt(pos).row() - 1 , 0);