QTableView 的 selectedItems 中选定行/行的顺序

Posted

技术标签:

【中文标题】QTableView 的 selectedItems 中选定行/行的顺序【英文标题】:order of selected rows/lines in QTableView's selectedItems 【发布时间】:2011-05-04 07:23:45 【问题描述】:

我正在使用 QTableWidget 并想将一些单元格复制到剪贴板。似乎 QTableWidget 只支持 selectedItems 方法。 出于某种原因,我将输出作为第一列,然后是第二列。不是:第一行,然后是第二行。这使得分离列/行变得有些困难。你知道出了什么问题吗?谢谢!

  QList<QTableWidgetItem *> selectedCells(TableView->selectedItems());
  QTableWidgetItem * item;

  mCopyByteArray.clear();

  foreach(item, selectedCells)
  
    mCopyByteArray.append(item->text());
    mCopyByteArray.append("\r\n");
  

构建时:

  TableView = new QTableWidget(); /* I know that name somehow is wrong ;) */
  TableView->setColumnCount(2);

  QStringList HHeaderList;
  HHeaderList << "Computer name" << "ServiceTag";
  TableView->setHorizontalHeaderLabels(HHeaderList);
  TableView->verticalHeader()->setVisible(false);
  TableView->setEditTriggers(QTableWidget::NoEditTriggers); 

有什么想法吗?谢谢!

【问题讨论】:

所以它会像这样通过 selectedCells 吗? (第 0 行,第 0 列)然后(第 1 行,第 0 列)等等?但是你想让它去(第 0 行,第 0 列)然后(第 0 行,第 1 列)? 没错!我认为这应该是正常的方式。 我写了一个小算法来按照你想要的顺序遍历 QList selectedCells。 【参考方案1】:

我写的这个算法应该可以解决问题:

QList<QTableWidgetItem *> selectedCells(TableView->selectedItems());

mCopyByteArray.clear();

QString text;
int row_count = TableView->rowCount();
int column_count = TableView->columnCount();

for( int i = 0; i < row_count; i++ )

    for( int j = 0; j < column_count; j++ )
    
        text = selectedCells.at( i + j * row_count )->text();

        mCopyByteArray.append( text );
        mCopyByteArray.append( "\r\n" );
    

【讨论】:

谢谢。我将您的解决方案修改为以下内容(见下文,还不熟悉 *** 论坛)。我认为这不是最好的,因为我们必须遍历每个 好的,因为我是新用户,我无法回答自己的问题……所以目前还没有代码详细信息。 奇怪的事情......我认为它以前有效,但现在它抛出了QList&lt;T&gt;::at, "index out of range" 错误。 是的,我刚刚注意到一个可怕的错误。我的解决方案仅适用于表格中的所有单元格。很抱歉您不能使用此解决方案;(【参考方案2】:

您可以改用QTableWidget::selectedRanges()。小例子:

#include <QList>
#include <QTableWidget>
#include <QTableWidgetSelectionRange>

/...

// you can have more than one selected areas in the table. So you can have more then one
// selected ranges
QList <QTableWidgetSelectionRange*> selectRanges(TableView->selectedRanges());

for (int i =0; i != selectRanges.size(); ++i) 
  QTableWidgetSelectionRange range = selectRanges.at(i);
  int top = range.topRow();
  int bottom = range.bottomRow();
  for (int i = top; i <= bottom; ++i) 
    QTableWidgetItem *item1 = TableView->itemAt(i, 0); //first column item
    QTableWidgetItem *item2 = TableView->itemAt(i, 1); //second column item
    // do desired stuff
  

注意:我不知道这种方法的性能问题。你可以检查一下。

【讨论】:

这看起来不错。但我认为它必须是TableView-&gt;selectedRanges()。此方法本身似乎返回 QTableWidgetSelectionRange 的 QList,而不是指向它的指针。接下来是我对 Qt foreach 的东西不是很熟悉,我得查一下。最后一件事:列/行号不是以 0 开头吗?所以TableView-&gt;itemAt(i, 1); 将是第二列项目,不是吗? @mattias:你无处不在。对于很多错误的输入,我深表歉意)我已经更正了答案并将 foreach 替换为 for。 @beduin:非常感谢您的帮助。我用j 替换了内部迭代器i,只是为了确保我们没有任何问题。奇怪的是itemAt 方法的返回值似乎都一样,并且指向我的 (row=0, col=0) 单元格。编辑:哎呀..我认为这是坐标.. @beduin:我用后增量替换了 i/j 的前增量。此外,我发现如果选择了不止一行,它就不再起作用了。最后我发现必须在for语句中切换顶部和底部(因为:底部> =顶部)。我想我现在也要添加 leftColumn 和 rightColumn 边框。 @matthias: 底部 >= 顶部 - 有趣的功能。)是的,通过列,您可以做类似的事情。希望它最终会起作用。))考虑前后增量运算符 - 建议使用前缀形式(您可以阅读More Effective C++的第6项)。【参考方案3】:

不是真正的答案,而是我发现的更多信息:

selectedItems() 函数返回所选项目的顺序似乎是它们被选择的顺序。

此外,如果QTableWidgetselectionBehavior 属性设置为SelectRows,则所选项目将按照选择行的顺序返回。例如,对于 2x3 表,其中行编号为“A”、“B”,列编号为“1”、“2”、“3”:如果选择 B2,然后选择 A1,则所选项目为返回为:B1,B2,B3,A1,A2,A3。

【讨论】:

以上是关于QTableView 的 selectedItems 中选定行/行的顺序的主要内容,如果未能解决你的问题,请参考以下文章

ComboBox MultiBinding如何绑定到SelectedItem的属性

ListBox.SelectedItems 的双向手动绑定实现?

TreeView 同步到视图模型中的 SelectedItem

UWP 组合框绑定到 SelectedItem 属性

Wpf:如何从嵌套的 DataGrid 中绑定 SelectedItem

在组合框中设置 SelectedItem