[英]How to Copy - Paste Multiple Items form QTableView created by QStandardItemModel to a text/excel file?
How can I copy and paste multiple items/values of a QTableView to a text/ excel file?如何将 QTableView 的多个项目/值复制并粘贴到文本/excel 文件?
My Code:我的代码:
tab_table_view = QtGui.QWidget()
self.Tab.insertTab(0, tab_table_view, self.File_Name)
self.tableView = QtGui.QTableView(tab_table_view)
self.tableView.setGeometry(QtCore.QRect(0, 0, 721, 571))
self.model = QtGui.QStandardItemModel(self)
self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection
This line self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection
helps with selecting multiple items in QTableView but when I do CTRL + C and paste it only pastes the last item or value of the selection?这一行
self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection
有助于在 QTableView 中选择多个项目,但是当我执行CTRL + C并粘贴它时,它只粘贴最后一个项目或选择的值?
I have seen the line self.tableView.setEditTriggers(QAbstractItemView.AllEditTriggers)
but this one only applies to a single item in the table and ignores the extended selection.我已经看到了
self.tableView.setEditTriggers(QAbstractItemView.AllEditTriggers)
这一行,但这只适用于表中的单个项目,并忽略了扩展选择。
Please help me this is the second time I am posting this question.请帮助我,这是我第二次发布此问题。 Now, I am wondering if it is even possible?
现在,我想知道这是否可能? Please let me know Anyone!
请让我知道任何人!
The difficulty here is that the selected cells in the table may be non-contiguous and not in any particular order.这里的困难在于表格中选定的单元格可能是不连续的,并且没有任何特定的顺序。 So the task is to calculate the smallest rectangle that will include all the selected cells, and then create a data structure from that which is suitable for passing to a csv writer.
因此,任务是计算将包含所有选定单元格的最小矩形,然后根据适合传递给 csv 编写器的数据结构创建数据结构。
Below is a demo script that does this (based on this previous answer - the additions have been commented):以下是执行此操作的演示脚本(基于此先前的答案- 已对添加内容进行了评论):
PyQt4 : PyQt4 :
# add imports
import sys, csv, io
import pandas as pd, numpy as np
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.model = QtGui.QStandardItemModel(self)
self.model.setSortRole(QtCore.Qt.UserRole)
self.tableView = QtGui.QTableView()
self.tableView.setSortingEnabled(True)
self.tableView.setModel(self.model)
# install event filter
self.tableView.installEventFilter(self)
self.button = QtGui.QPushButton('Open CSV', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.tableView)
layout.addWidget(self.button)
# add event filter
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.KeyPress and
event.matches(QtGui.QKeySequence.Copy)):
self.copySelection()
return True
return super(Window, self).eventFilter(source, event)
# add copy method
def copySelection(self):
selection = self.tableView.selectedIndexes()
if selection:
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
rowcount = rows[-1] - rows[0] + 1
colcount = columns[-1] - columns[0] + 1
table = [[''] * colcount for _ in range(rowcount)]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
table[row][column] = index.data()
stream = io.StringIO()
csv.writer(stream).writerows(table)
QtGui.qApp.clipboard().setText(stream.getvalue())
def handleButton(self):
filters = (
'CSV files (*.csv *.txt)',
'Excel Files (*.xls *.xml *.xlsx *.xlsm)',
)
path, filter = QtGui.QFileDialog.getOpenFileNameAndFilter(
self, 'Open File', '', ';;'.join(filters))
if path:
csv = filter.startswith('CSV')
if csv:
dataframe = pd.read_csv(path)
else:
dataframe = pd.read_excel(path)
self.model.setRowCount(0)
dateformat = '%m/%d/%Y'
rows, columns = dataframe.shape
for row in range(rows):
items = []
for column in range(columns):
field = dataframe.iat[row, column]
if csv and isinstance(field, str):
try:
field = pd.to_datetime(field, format=dateformat)
except ValueError:
pass
if isinstance(field, pd.tslib.Timestamp):
text = field.strftime(dateformat)
data = field.timestamp()
else:
text = str(field)
if isinstance(field, np.number):
data = field.item()
else:
data = text
item = QtGui.QStandardItem(text)
item.setData(data, QtCore.Qt.UserRole)
items.append(item)
self.model.appendRow(items)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 150, 600, 400)
window.show()
sys.exit(app.exec_())
PyQt5 : PyQt5 :
# add imports
import sys, csv, io
import pandas as pd, numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.model = QtGui.QStandardItemModel(self)
self.model.setSortRole(QtCore.Qt.UserRole)
self.tableView = QtWidgets.QTableView()
self.tableView.setSortingEnabled(True)
self.tableView.setModel(self.model)
# install event filter
self.tableView.installEventFilter(self)
self.button = QtWidgets.QPushButton('Open CSV', self)
self.button.clicked.connect(self.handleButton)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tableView)
layout.addWidget(self.button)
# add event filter
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.KeyPress and
event.matches(QtGui.QKeySequence.Copy)):
self.copySelection()
return True
return super(Window, self).eventFilter(source, event)
# add copy method
def copySelection(self):
selection = self.tableView.selectedIndexes()
if selection:
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
rowcount = rows[-1] - rows[0] + 1
colcount = columns[-1] - columns[0] + 1
table = [[''] * colcount for _ in range(rowcount)]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
table[row][column] = index.data()
stream = io.StringIO()
csv.writer(stream).writerows(table)
QtWidgets.qApp.clipboard().setText(stream.getvalue())
def handleButton(self):
filters = (
'CSV files (*.csv *.txt)',
'Excel Files (*.xls *.xml *.xlsx *.xlsm)',
)
path, filter = QtWidgets.QFileDialog.getOpenFileName(
self, 'Open File', '', ';;'.join(filters))
if path:
csv = filter.startswith('CSV')
if csv:
dataframe = pd.read_csv(path)
else:
dataframe = pd.read_excel(path)
self.model.setRowCount(0)
dateformat = '%m/%d/%Y'
rows, columns = dataframe.shape
for row in range(rows):
items = []
for column in range(columns):
field = dataframe.iat[row, column]
if csv and isinstance(field, str):
try:
field = pd.to_datetime(field, format=dateformat)
except ValueError:
pass
if isinstance(field, pd.Timestamp):
text = field.strftime(dateformat)
data = field.timestamp()
else:
text = str(field)
if isinstance(field, np.number):
data = field.item()
else:
data = text
item = QtGui.QStandardItem(text)
item.setData(data, QtCore.Qt.UserRole)
items.append(item)
self.model.appendRow(items)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 150, 600, 400)
window.show()
sys.exit(app.exec_())
To copy and paste multiple items from qtableview
created by qstandarditemmodel
without considering rectangular form and by selecting non-contiguous row or column in C++ is.要从
qtableview
创建的qstandarditemmodel
中复制和粘贴多个项目,而不考虑矩形形式,并且在 C++ 中选择不连续的行或列。
void CustomTableView::keyPressEvent(QKeyEvent * event) {
this -> setSelectionBehavior(QAbstractItemView::SelectRows);
this -> setSelectionMode(QAbstractItemView::MultiSelection);
QModelIndexList selectedRows = selectionModel() -> selectedRows();
QModelIndexList selectedColumns = selectionModel() -> selectedColumns();
if (event -> key() == Qt::Key_Insert) {
tblview_model -> customInsertRows();
} else if (event -> key() == Qt::Key_Delete) {
if (!selectedRows.isEmpty())
model() -> removeRows(selectedRows.at(0).row(),
selectedRows.size());
} else if (event -> matches(QKeySequence::Paste)) {
if (copyPasteEnabled == true) {
text = QApplication::clipboard() -> text();
if (!text.isEmpty()) {
tblview_model -> pasteData(text);
}
}
}
if (!selectedIndexes().isEmpty()) {
if (event -> matches(QKeySequence::Copy)) {
QString text;
QStringList hdr_lst;
const std::vector < std::string > & hdrs = tblview_model -> getHeader();
QItemSelectionRange range = selectionModel() -> selection().first();
if (!selectedColumns.isEmpty()) {
for (auto j = 0; j < selectedColumns.size(); ++j) {
std::string hd = hdrs[selectedColumns.at(j).column()];
if (std::find(hdrs.begin(), hdrs.end(), hd) != hdrs.end())
hdr_lst << QString::fromStdString(hd);
}
text += hdr_lst.join("\t");
text += "\n";
for (auto i = 0; i < tblview_model -> rowCount(); ++i) {
QStringList rowContents;
for (auto j = 0; j < selectedColumns.size(); ++j) {
if (!isColumnHidden(j)) {
rowContents << model() -> index(i, selectedColumns.at(j).column()).data().toString();
}
}
text += rowContents.join("\t");
text += "\n";
}
} else if (!selectedRows.isEmpty()) {
for (auto h: hdrs) {
hdr_lst << QString::fromStdString(h);
}
text += hdr_lst.join("\t");
text += "\n";
//for (auto i = range.top(); i <= range.bottom(); ++i)
for (auto i = 0; i < selectedRows.size(); ++i) {
QStringList rowContents;
for (auto j = 0; j <= tblview_model -> columnCount(); ++j) {
if (!isColumnHidden(j)) {
rowContents << model() -> index(selectedRows.at(i).row(), j).data().toString();
}
}
text += rowContents.join("\t");
text += "\n";
}
}
QApplication::clipboard() -> setText(text);
} else
QTableView::keyPressEvent(event);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.