Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.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++ QTableView中标题单元格中的复选框_C++_Qt_Qt4 - Fatal编程技术网

C++ QTableView中标题单元格中的复选框

C++ QTableView中标题单元格中的复选框,c++,qt,qt4,C++,Qt,Qt4,我想要一个简单的列标题,带有一个复选框,用于选择/取消选择QTableView中的所有行。单击标题中的复选框会导致选择或取消选择所有行 当我想在表格单元格中添加复选框时,我必须返回数据(..)中所需模型索引的Qt::CheckStateRole的检查状态,如下所示。这是预期的工作 QVariant MyModel::data( const QModelIndex & rIndex, int iRole) const { ... if (iRole == Qt::Qt:

我想要一个简单的列标题,带有一个复选框,用于选择/取消选择QTableView中的所有行。单击标题中的复选框会导致选择或取消选择所有行

当我想在表格单元格中添加复选框时,我必须返回数据(..)中所需模型索引的Qt::CheckStateRole的检查状态,如下所示。这是预期的工作

QVariant MyModel::data( const QModelIndex & rIndex, int iRole) const
{
    ...

    if (iRole == Qt::Qt::CheckStateRole)
    {
        return checkstate;
    }

}
但是,当我想在标题单元格中添加复选框时,上述方法不起作用。这是我的示例代码

QVariant MyModel::headerData( int iSection, Qt::Orientation eOrientation, int iRole) const
{
    ...

    if (iRole == Qt::CheckStateRole)
    {
        return checkstate;
    }

}
与data()函数一样,QTableView不会使用Qt::CheckStateRole在我的模型中调用headerData()函数

为什么会有这种行为?如何仅通过修改自定义表格模型在标题单元格中插入复选框


(我不想为此创建自定义QTableView或QHeaderView)

您不能这样做-默认情况下,Qt不支持标题中的复选框。您可以使用自定义的
QHeaderView

阅读更多信息及其实现。这里有一点修改/修复(复选框显示为禁用,重绘不起作用)代码来自接受答案中的链接

h

.cpp

用法


我很惊讶这样一个黑客解决方案被推荐和使用

首先:检查状态应存储在模型中。所有工具都已存在

bool MyModel::setHeaderData(int index, Qt::Orientation orient, const QVariant& val, int role)
{
  if(Qt::Vertical != orient)
    return Base::setHeaderData(index, orient, val, role);

  storeCheckState(index, val);
  emit headerDataChanged(orient, index, index);
  return true;
}

QVariant MyModel::headerData(int index, Qt::Orientation o, int role) const
{
    if(Qt::Vertical != orient)
      return Base::headerData(index, o, role);

    switch(role)
    {
    ...
    case Qt::CheckStateRole:
      return fetchCheckState(index);
    }

  return Base::headerData(index, o, role);
}
Second:我们只需处理标题上的点击信号即可切换选中状态

connect(header, &QHeaderView::sectionClicked, receiver
        , [receiver](int sec)
{
  const auto index = logicalIndex(sec);
  model()->setHeaderData(index
                         , Qt::Vertical
                         , Qt::CheckState(model()->headerData(index, Qt::Vertical, Qt::CheckStateRole).toUInt()) != Qt::Checked ? Qt::Checked : Qt::Unchecked
                         , Qt::CheckStateRole);
});
第三名: 在这一点上,我们有全功能的检查行为,唯一缺少的部分是可视化。最明智的方法是再次使用模型,利用
Qt::DecorationRole
。下面是一个虚拟实现:

QVariant MyModel::headerData(int index, Qt::Orientation o, int role) const
{
    if(Qt::Vertical != orient)
      return Base::headerData(index, o, role);

    switch(role)
    {
      case Qt::DecorationRole:
      {
        QPixmap p{12,12};
        p.fill(Qt::CheckState(headerData(index, o, Qt::CheckStateRole).toUInt()) ? Qt::green : Qt::red);
        return p;
       }
       break;
    ...
    }

  return Base::headerData(index, o, role);
}
当然,可以使用样式化绘图在那里绘制一个真正的复选框

注意,此解决方案不需要子分类和自定义小部件


此外,检查状态与视图/UI分离。唯一的缺点是视觉效果是由模型处理的,但这是可选的-可以使用任何方式绘制检查状态,包括备选答案中的检查状态

如果您有时间,请从第三方资源复制或重新实现代码。只有链接的答案的问题是链接到站点的答案经常会消失,而答案变得毫无用处
bool MyModel::setHeaderData(int index, Qt::Orientation orient, const QVariant& val, int role)
{
  if(Qt::Vertical != orient)
    return Base::setHeaderData(index, orient, val, role);

  storeCheckState(index, val);
  emit headerDataChanged(orient, index, index);
  return true;
}

QVariant MyModel::headerData(int index, Qt::Orientation o, int role) const
{
    if(Qt::Vertical != orient)
      return Base::headerData(index, o, role);

    switch(role)
    {
    ...
    case Qt::CheckStateRole:
      return fetchCheckState(index);
    }

  return Base::headerData(index, o, role);
}
connect(header, &QHeaderView::sectionClicked, receiver
        , [receiver](int sec)
{
  const auto index = logicalIndex(sec);
  model()->setHeaderData(index
                         , Qt::Vertical
                         , Qt::CheckState(model()->headerData(index, Qt::Vertical, Qt::CheckStateRole).toUInt()) != Qt::Checked ? Qt::Checked : Qt::Unchecked
                         , Qt::CheckStateRole);
});
QVariant MyModel::headerData(int index, Qt::Orientation o, int role) const
{
    if(Qt::Vertical != orient)
      return Base::headerData(index, o, role);

    switch(role)
    {
      case Qt::DecorationRole:
      {
        QPixmap p{12,12};
        p.fill(Qt::CheckState(headerData(index, o, Qt::CheckStateRole).toUInt()) ? Qt::green : Qt::red);
        return p;
       }
       break;
    ...
    }

  return Base::headerData(index, o, role);
}