I have a QTableView
that displays parsed data from a file. I open the file, parse it into different columns based on its delimiter for each line in the file, and then output it to the view. I am using a QStandardItemModel
for this.
Relevant code that sets up the model:
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);
Note that I have it so that I can drag the column headers around to reorder the columns in the table. This will be important later.
I also have the view set up so that I can select an entire row (or individual cells), hit Ctrl+C, and have the contents of the selection copy to the clipboard. I made a separate model for the selected items/rows:
QApplication::clipboard()->clear();
QItemSelectionModel* selection = ui->tableView->selectionModel();
QModelIndexList indexes = selection->selectedIndexes();
QString clipboardString;
QModelIndexList selectedIndexes = ui->tableView->selectionModel()->selectedIndexes();
I then have some code to handle what happens if the selection spans multiple rows. I set up a QModelIndex
for this. The implementation for this is simple. I use a for loop to iterate through the indices of the selected cells. If the next index (column) is on the same row as the current one, I add that data to the variable I will eventually write to the clipboard and append a tab (t
) to it (since I want the copied cells to be delimited by tabs so I can easily copy to the clipboard and paste into Excel if I want). If the next index (column) is on a DIFFERENT row, then I append a line break (n
). Here is the code:
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);
Here's where I have a problem. If I rearrange the columns in my view, the index check breaks. My untouched view looks like this:
+------+------+
| Col1 | Col2 |
+------+------+
| A | B |
| W | X |
+------+------+
If I select any of the values in the table, I can Ctrl+C and paste as expected. No problem. A copy and paste after selecting this entire table would result in this output:
A B
W X
However, if I drag Col1
over to where Col2
is, effectively switching them to look like this:
+------+------+
| Col2 | Col1 |
+------+------+
| B | A |
| X | W |
+------+------+
...and select the entire thing and paste it, I get this output:
B
X
A
W
This is obviously not what I want and it seems to be adding a line break (n
) after every selected cell.
My qDebug()
outputs for the first, unmodified table are:
next.row() 0
current.row() 0
next.row() 1
current.row() 0
next.row() 1
current.row() 1
My qDebug()
outputs for the second, rearranged table are:
next.row() 1
current.row() 0
next.row() 0
current.row() 1
next.row() 1
current.row() 0
What am I doing wrong here? Why would it matter that the columns in the view are rearranged?
Aucun commentaire:
Enregistrer un commentaire