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<T>::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->selectedRanges()
。此方法本身似乎返回 QTableWidgetSelectionRange 的 QList,而不是指向它的指针。接下来是我对 Qt foreach 的东西不是很熟悉,我得查一下。最后一件事:列/行号不是以 0 开头吗?所以TableView->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()
函数返回所选项目的顺序似乎是它们被选择的顺序。
此外,如果QTableWidget
的selectionBehavior
属性设置为SelectRows
,则所选项目将按照选择行的顺序返回。例如,对于 2x3 表,其中行编号为“A”、“B”,列编号为“1”、“2”、“3”:如果选择 B2,然后选择 A1,则所选项目为返回为:B1,B2,B3,A1,A2,A3。
【讨论】:
以上是关于QTableView 的 selectedItems 中选定行/行的顺序的主要内容,如果未能解决你的问题,请参考以下文章
ComboBox MultiBinding如何绑定到SelectedItem的属性
ListBox.SelectedItems 的双向手动绑定实现?
TreeView 同步到视图模型中的 SelectedItem