我有一个QTableView
,它显示一个文件的解析数据。我打开文件,根据文件中每行的分隔符将其解析为不同的列,然后将其输出到视图。我使用QStandardItemModel
来完成此任务。
设置模型的相关代码:
QStandardItemModel* model = new QStandardItemModel(this);
int lineIndex = 0;
QStringList headers;
headers << "Col1" << "Col2";
model->setHorizontalHeaderLabels(headers);
file.seek(0);
QTextStream inData(&file);
while (!inData.atEnd()){
QString line = inData.readLine();
QStringList lineToken = line.split(":"/*, QString::SkipEmptyParts*/);
for (int j = 0; j < lineToken.size(); j++) {
QString value = lineToken.at(j);
QStandardItem* item = new QStandardItem(value);
model->setItem(lineIndex, j, item);
}
lineIndex++;
}
ui->tableView->setModel(model);
ui->tableView->horizontalHeader()->setSectionsMovable(true);
请注意,我有它,以便我可以拖动列标题左右,以重新排序表中的列。这将是重要的稍后。
我还设置了视图,这样我就可以选择整行(或单个单元格),按Ctrl+C,并将所选内容复制到剪贴板。我为所选项目/行创建了一个单独的模型:
QApplication::clipboard()->clear();
QItemSelectionModel* selection = ui->tableView->selectionModel();
QModelIndexList indexes = selection->selectedIndexes();
QString clipboardString;
QModelIndexList selectedIndexes = ui->tableView->selectionModel()->selectedIndexes();
然后,我用一些代码来处理如果选择跨越多行会发生什么。我为此设置了一个QModelIndex
。它的实现很简单。我使用一个for循环来迭代所选单元格的索引。如果下一个索引(列)与当前列在同一行上,我将该数据添加到变量中,最终将写入剪贴板并附加一个选项卡(\t
)到它(因为我希望复制的单元格用制表符分隔,这样我就可以轻松地复制到剪贴板,并根据需要粘贴到Excel中)。(column)在不同的行上,那么我添加一个换行符(\n
)。
for (int i = 0; i < selectedIndexes.count(); ++i)
{
QModelIndex current = selectedIndexes[i];
QString displayText = current.data(Qt::DisplayRole).toString();
// If there exists another column beyond this one.
if (i + 1 < selectedIndexes.count()) {
QModelIndex next = selectedIndexes[i+1];
// If the column is on different row, the clipboard should take note.
qDebug() << "next.row()" << next.row();
qDebug() << "current.row()" << current.row();
if (next.row() != current.row()){
displayText.append("\n");
} else {
// Otherwise append a column separator.
displayText.append("\t");
}
}
clipboardString.append(displayText);
}
QApplication::clipboard()->setText(clipboardString);
这就是我遇到的问题。如果我重新排列视图中的列,索引检查就会中断。我的未修改视图如下所示:
+------+------+
| Col1 | Col2 |
+------+------+
| A | B |
| W | X |
+------+------+
如果我选择表中的任何值,我可以按Ctrl+C并按预期粘贴。没有问题。选择整个表后复制并粘贴将导致以下输出:
A B
W X
但是,如果我将Col1
拖动到Col2
所在的位置,实际上会将它们切换为如下所示:
+------+------+
| Col2 | Col1 |
+------+------+
| B | A |
| X | W |
+------+------+
......然后选择整个内容并粘贴,我得到以下输出:
B
X
A
W
这显然不是我想要的,它似乎是添加一个换行符(\n
)后,每个选定的单元格。
第一个未修改的表的qDebug()
输出为:
next.row() 0
current.row() 0
next.row() 1
current.row() 0
next.row() 1
current.row() 1
第二个重新排列的表的qDebug()
输出为:
next.row() 1
current.row() 0
next.row() 0
current.row() 1
next.row() 1
current.row() 0
我在这里做错了什么?重新排列视图中的列有什么关系?
3条答案
按热度按时间fquxozlt1#
以下方法似乎有效...
注意索引列是如何使用...
不管怎样,看看这是否更接近你的需要。
6yt4nkrj2#
出于您的目的,最好使用 * 选择范围 *。
基本思想是逐行处理选择。
QItemSelectionModel::selection()
返回QItemSelection
,QItemSelection
是 * 选择范围 * 的列表。* 选择范围 * 是所选索引的连续矩形集合。yqhsw0fo3#
要复制带有标题的QTable视图中的选择,可覆盖按键事件并按如下方式使用。
无效按键事件(QKeyEvent * 事件){