我有一個QTableView
顯示來自文件的解析數據。我打開文件,根據文件中每行的分隔符將其解析爲不同的列,然後將其輸出到視圖。我爲此使用了QStandardItemModel
。正確地複製QTableView中的選擇(模型索引問題)
相關代碼,樹立典型:
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中,如果我想)。如果下一個索引(列)是在不同的行,然後我追加一個換行符(\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
這顯然不是我想要的,它似乎是添加一條線ak(\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
我在做什麼錯在這裏?爲什麼視圖中的列會重新排列?
您似乎認爲'QItemSelectionRange'將連續存儲屬於給定行的所有索引。我不確定是否有這樣的保證。不要在循環中構建一個QString,而是嘗試構造像'map>',然後處理它以生成所需的最終QString。 –
我看到你在說什麼,但在我將其處理成最終字符串的情況下,我仍然需要了解列的順序以及用戶如何更改它們。我想我可能能夠捕捉到列重新排序時發出的信號。那麼,或者我創建一組與新列順序相對應的索引。 – orbit