【问题标题】:Get cell position of QCheckBox in QTableWidget获取 QTableWidget 中 QCheckBox 的单元格位置
【发布时间】:2015-08-26 05:08:21
【问题描述】:

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

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

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

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

【问题讨论】:

  • 如何将此复选框添加到表格小部件?你用item delegate吗?我怀疑不是,因为您没有仔细阅读文档,所以您正在与QTableWidget 战斗。检查我的回答并更新您的问题以提供更多详细信息。
  • 我会将数据源传递给 tablewidget,并使用 wtablewidget 中数据源中的值填充复选框。

标签: c++ qt


【解决方案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】:

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

    【讨论】:

      【解决方案3】:

      如果你坚持使用 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);
                   ...
               }
           }
      }
      

      【讨论】:

        【解决方案4】:

        你做错了。您没有显示代码,因此很难说到底出了什么问题(我只是在怀疑)。

        无论如何,这是 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)));
        

        【讨论】:

          【解决方案5】:
          QPoint pos = tableWidget->mapFromGlobal(QCursor::pos());
          QTableWidgetItem* item = tableWidget->item(tableWidget->indexAt(pos).row() - 1 , 0);
          

          一旦你得到了物品,你就得到了位置。

          【讨论】:

            猜你喜欢
            • 2020-06-07
            • 1970-01-01
            • 2020-12-30
            • 2011-06-27
            • 1970-01-01
            • 1970-01-01
            • 2011-10-01
            • 2012-08-19
            • 2013-06-07
            相关资源
            最近更新 更多