我正在设计一个具有多个功能的用户界面。在.ui上,我有一个QTableView。右键单击表格视图后,我将打开一个具有相同QTableView的对话框,因此以这种方式更易于可视化数据。
在尝试将某些值复制并粘贴后,从一个单元格复制到另一个单元格,或从一列复制到另一列,我有一个奇怪的行为,我不知道如何解决。下面,我尝试复制ctrl+C
所选单元格:
然后将其粘贴ctrl+V
,我得到一个奇怪的行为:
出于某些原因,我将标题“经度”复制到第二行而不是数字24。另外,将数字200压入下面。
此代码还允许从QTableView复制并粘贴到Excel文件,此功能运行良好,但我决定将其包含在说明中,以便您了解如何处理所有循环。
editdialog.h
private:
Ui::editLeftTableDialog *ui;
QSqlTableModel *mModel;
QAction *mActionAppendRow;
QAction *mActionDeleteRow;
protected:
void keyPressEvent(QKeyEvent *event);
editdialog.cpp
void editLeftTableDialog::keyPressEvent(QKeyEvent *event)
{
{
QAbstractItemModel * modelRemoveAdd = ui->tableViewLeft->model();
QItemSelectionModel *selectionModel = ui->tableViewLeft->selectionModel();
QModelIndexList selectedRows = selectionModel->selectedRows();
QAbstractItemModel * modelNew = ui->tableViewLeft->model();
QItemSelectionModel *selectedIndexes = ui->tableViewLeft->selectionModel();
QModelIndexList selectedInd = selectedIndexes->selectedIndexes();
// Make sure one row is selected
if(!selectedRows.isEmpty())
{
if(event->key() == Qt::Key_Insert)
mModel->insertRows(selectedRows.at(0).row(),
selectedRows.size());
else if(event->key() == Qt::Key_Delete)
mModel->removeRows(selectedRows.at(0).row(),
selectedRows.size());
}
// Make sure one cell selected
if(!selectedInd.isEmpty())
{
if(event->key() == Qt::Key_Delete)
foreach(QModelIndex index, selectedInd)
mModel->setData(index, QString());
else if(event->matches(QKeySequence::Copy))
{
QString text;
QItemSelectionRange range = ui->tableViewLeft->selectionModel()->selection().first();
for(auto i = range.top(); i <= range.bottom(); ++i)
{
QStringList rowContents;
for(auto j = range.left(); j <= range.right(); ++j)
rowContents << mModel->index(i,j).data().toString();
text += rowContents.join("\t");
text += "\n";
}
QApplication::clipboard()->setText(text);
}
else if(event->matches(QKeySequence::Paste))
{
QString text = QApplication::clipboard()->text();
QStringList rowContents = text.split("\n", QString::SkipEmptyParts);
QModelIndex initIndex = ui->tableViewLeft->selectionModel()->selectedIndexes().at(0);
auto initRow = initIndex.row();
auto initCol = initIndex.column();
for(auto i = 0; i < rowContents.size(); i++)
{
QStringList columnContents = rowContents.at(i).split("\t");
for(auto j = 0; j < columnContents.size(); j++)
{
mModel->setData(mModel->index(initRow + i, initCol + j), columnContents.at(j));
}
}
}
}
}
// Copy from QTableView to an Excel or CSV file happens here and works well
QAbstractItemModel * model = ui->tableViewLeft->model();
QItemSelectionModel *selection = ui->tableViewLeft->selectionModel();
QModelIndexList indices = selection->selectedIndexes();
if(indices.isEmpty())
return;
QMap<int, bool> selectedColumnsMap;
Q_FOREACH (QModelIndex current, indices)
{
selectedColumnsMap[current.column()] = true;
}
QList<int> selectedColumns = selectedColumnsMap.uniqueKeys();
int minCol = selectedColumns.first();
// prepend headers for selected columns
QString selectedText;
Q_FOREACH (int column, selectedColumns)
{
selectedText += ui->tableViewLeft->model()->headerData(column, Qt::Horizontal, Qt::DisplayRole).toString();
if(column != selectedColumns.last())
selectedText += QLatin1Char('\t');
}
selectedText += QLatin1Char('\n');
qSort(indices);
int lastRow = indices.first().row();
int lastColumn = minCol;
Q_FOREACH(QModelIndex current, indices)
{
if(current.row() != lastRow)
{
selectedText += QLatin1Char('\n');
lastColumn = minCol;
lastRow = current.row();
}
if(current.column() != lastColumn)
{
for(int i = 0; i < current.column() - lastColumn; ++i)
selectedText += QLatin1Char('\t');
lastColumn = current.column();
}
selectedText += ui->tableViewLeft->model()->data(current).toString();
}
selectedText += QLatin1Char('\n');
QApplication::clipboard()->setText(selectedText);
}
答案 0 :(得分:1)
凌乱的代码总是会带来问题,因此,我将不对其进行分析,但将提出一种适当的方法,在该方法中,我们为每个任务创建一个函数,并且可以使用QShorcut代替使用keyPressEvent:< / p>
editlefttabledialog.h
#ifndef EDITLEFTTABLEDIALOG_H
#define EDITLEFTTABLEDIALOG_H
#include <QDialog>
class QSqlTableModel;
namespace Ui {
class EditLeftTableDialog;
}
class EditLeftTableDialog : public QDialog
{
Q_OBJECT
public:
explicit EditLeftTableDialog(QWidget *parent = nullptr);
~EditLeftTableDialog();
private slots:
void copy();
void paste();
private:
Ui::EditLeftTableDialog *ui;
QSqlTableModel *mModel;
};
#endif // EDITLEFTTABLEDIALOG_H
editlefttabledialog.cpp
#include "editlefttabledialog.h"
#include "ui_editlefttabledialog.h"
#include <QShortcut>
#include <QSqlTableModel>
#include <QClipboard>
EditLeftTableDialog::EditLeftTableDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::EditLeftTableDialog)
{
ui->setupUi(this);
mModel = new QSqlTableModel(this);
mModel->setTable("test_table");
mModel->select();
ui->tableViewLeft->setModel(mModel);
QShortcut *shortcut_copy = new QShortcut(QKeySequence::Copy, ui->tableViewLeft);
connect(shortcut_copy, &QShortcut::activated, this, &EditLeftTableDialog::copy);
QShortcut *shortcut_paste = new QShortcut(QKeySequence::Paste, ui->tableViewLeft);
connect(shortcut_paste, &QShortcut::activated, this, &EditLeftTableDialog::paste);
}
EditLeftTableDialog::~EditLeftTableDialog()
{
delete ui;
}
void EditLeftTableDialog::copy()
{
QString text;
QItemSelectionRange selection_range = ui->tableViewLeft->selectionModel()->selection().first();
for(int i=selection_range.top(); i <= selection_range.bottom(); i++){
QStringList row_content;
for(int j= selection_range.left(); j <= selection_range.right(); j++){
row_content << mModel->index(i,j).data().toString();
}
text += row_content.join(QChar('\t')) + QChar('\n');
}
QApplication::clipboard()->setText(text);
}
void EditLeftTableDialog::paste()
{
QModelIndex start = ui->tableViewLeft->selectionModel()->selectedIndexes().first();
QString text = QApplication::clipboard()->text();
int i=0, j=0;
for(const QString & row_string: text.split("\n", QString::SkipEmptyParts)){
j=0;
for(const QString & col: row_string.split("\t", QString::SkipEmptyParts)){
QModelIndex ix = mModel->index(start.row() + i , start.column()+ j);
if(ix.isValid()){
ui->tableViewLeft->model()->setData(ix, col);
mModel->submit();
}
j++;
}
i++;
}
}