如何在Qt中移动行(在QTableWidget中)

时间:2017-09-28 17:21:52

标签: c++ qt c++11

令人遗憾的是,Qt开发人员跳过这个表中非常重要的部分... 移动行(可能是选定的行),检查碰撞并支持带间隙的选择 - 现在有一个自己实施。

幸运的是,我花了一整天时间创建了这样的自包含功能,可以轻松修改以移动与表/列表相关的任何内容(目前它移动 所选项目 - 第二行)。更有趣的是,我能够轻松地(大约3行)添加对方向参数的支持,而不是单独的函数。

我没有考虑过这个问题,但是一次移动超过1个项目也是可能的 - 尽管我没有必要这样做。

感谢任何建议和错误测试 ~~享受

1 个答案:

答案 0 :(得分:0)

代码在(技术上很简单)非常复杂,即使没有检查碰撞,间隙和表格结尾,所以我现在不打算解释它,但如果这引起兴趣,我可能会在以后发生。

此外,这段代码是 c ++ 11 ,不确定在没有新实现的情况下编译它需要多少重写,但只是抬头。

void moveSelected(QTableWidget* _table, MVDIRECTION _dir) {
  QList<QTableWidgetItem*> list = _table->selectedItems();

  if (list.count() == 0) {
    perror("moveSelected(...) - no items supplied (NULL items)!\n");
    return;
  }
  if (_dir == Down)
    std::reverse(list.begin(), list.end());

  int r_limit = (_dir == Up) ?0 :(_table->rowCount() - 1);
  int r_last = list.first()->row() + _dir;
  bool block = false;

  QTableWidgetItem* buffer = NULL;

  if (list.first()->row() != r_limit)
    buffer = _table->takeItem(list.first()->row() + _dir, 0);

  for (auto &item : list) {
    if ( item->row() != (r_last - _dir) ) {
      _table->setItem(r_last, 0, buffer);
      buffer = _table->takeItem(item->row() + _dir, 0);
      block = false;
    }

    r_last = item->row();

    if ( (item->row() != r_limit) & (!block)) {
      QTableWidgetItem* _item = _table->takeItem(item->row(), 0);
      _table->setItem(r_last + _dir, 0, _item);
    }
    else if (!block) block = true;
  }

  if (buffer) _table->setItem(list.last()->row() - _dir, 0, buffer);
}

哦是的,只是为了便于阅读,MVDIRECTION枚举:

enum MVDIRECTION {
  Up = -1,
  Down = 0
};