Copy/Paste pyqt4 中 QTableView 的多个项目?
Copy/Paste multiple items from QTableView in pyqt4?
我们可以使用 self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
从 QTableView select 多个项目(部分行和部分列),但是在 selecting 一些行和列(部分和部分)之后,如果我这样做CTRL+C 并将其粘贴到记事本中它只粘贴一项(tableView 中的一个值)?
我的代码:
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.model.setSortRole(QtCore.Qt.UserRole)
self.tableView.setModel(self.model)
self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) '''this helps for selecting multiple items but not able to copy and paste multiple values to a text/ excel (it only copies single value)'''
我们如何复制和粘贴多个项目?
QAbstractItemView.ExtendedSelection
当用户以通常的方式选择一个项目时,选择被清除并选择新项目。但是,如果用户在单击某个项目时按下 Ctrl 键,则单击的项目会切换,所有其他项目将保持 不变 。如果用户在单击某个项目 的同时按下 Shift 键,则会选择或取消选择当前项目和所单击项目之间的所有项目,具体取决于所单击项目的状态。可以通过将鼠标拖到它们上面来选择多个项目。
你也可以使用
QAbstractItemView.MultiSelection
self.tableView.installEventFilters(self)
现在,添加事件过滤器:
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)
复制函数:
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())
非常感谢上面的@learncode 评论,我设法得到了复制部分。此外,我修改了一点以支持复制到 Excel 以及相应的单元格顺序:
def copySelection(self):
selection = self.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, delimiter='\t').writerows(table)
QtWidgets.qApp.clipboard().setText(stream.getvalue())
return
除了复制,我还创建了粘贴部分。根据用户选择的单元格范围(一个单元格或单元格范围),此代码段支持粘贴不同形状的数据。
def pasteSelection(self):
selection = self.selectedIndexes()
if selection:
model = self.model()
buffer = QtWidgets.qApp.clipboard().text()
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
reader = csv.reader(io.StringIO(buffer), delimiter='\t')
if len(rows) == 1 and len(columns) == 1:
for i, line in enumerate(reader):
for j, cell in enumerate(line):
model.setData(model.index(rows[0]+i,columns[0]+j), cell)
else:
arr = [ [ cell for cell in row ] for row in reader]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
model.setData(model.index(index.row(), index.column()), arr[row][column])
return
这个答案扩展了@learncode 和@Frederick Li 的答案以适应
的情况
- 行列未按升序排列
- 视图中隐藏了某些行 and/or 列。
它还包括扩展事件过滤器以处理粘贴的代码。
class TableView(QTableView):
def __init__(self, *args, **kwargs):
super(TableView, self).__init__(*args, **kwargs)
self.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.KeyPress and event.matches(QKeySequence.Copy):
self.copy_selection()
return True
elif event.type() == QEvent.KeyPress and event.matches(QKeySequence.Paste):
self.paste_selection()
return True
return super(TableView, self).eventFilter(source, event)
def copy_selection(self):
selection = self.selectedIndexes()
if selection:
all_rows = []
all_columns = []
for index in selection:
if not index.row() in all_rows:
all_rows.append(index.row())
if not index.column() in all_columns:
all_columns.append(index.column())
visible_rows = [row for row in all_rows if not self.isRowHidden(row)]
visible_columns = [
col for col in all_columns if not self.isColumnHidden(col)
]
table = [[""] * len(visible_columns) for _ in range(len(visible_rows))]
for index in selection:
if index.row() in visible_rows and index.column() in visible_columns:
selection_row = visible_rows.index(index.row())
selection_column = visible_columns.index(index.column())
table[selection_row][selection_column] = index.data()
stream = io.StringIO()
csv.writer(stream, delimiter="\t").writerows(table)
QApplication.clipboard().setText(stream.getvalue())
def paste_selection(self):
selection = self.selectedIndexes()
if selection:
model = self.model()
buffer = QApplication.clipboard().text()
all_rows = []
all_columns = []
for index in selection:
if not index.row() in all_rows:
all_rows.append(index.row())
if not index.column() in all_columns:
all_columns.append(index.column())
visible_rows = [row for row in all_rows if not self.isRowHidden(row)]
visible_columns = [
col for col in all_columns if not self.isColumnHidden(col)
]
reader = csv.reader(io.StringIO(buffer), delimiter="\t")
arr = [[cell for cell in row] for row in reader]
if len(arr) > 0:
nrows = len(arr)
ncols = len(arr[0])
if len(visible_rows) == 1 and len(visible_columns) == 1:
# Only the top-left cell is highlighted.
for i in range(nrows):
insert_rows = [visible_rows[0]]
row = insert_rows[0] + 1
while len(insert_rows) < nrows:
row += 1
if not self.isRowHidden(row):
insert_rows.append(row)
for j in range(ncols):
insert_columns = [visible_columns[0]]
col = insert_columns[0] + 1
while len(insert_columns) < ncols:
col += 1
if not self.isColumnHidden(col):
insert_columns.append(col)
for i, insert_row in enumerate(insert_rows):
for j, insert_column in enumerate(insert_columns):
cell = arr[i][j]
model.setData(model.index(insert_row, insert_column), cell)
else:
# Assume the selection size matches the clipboard data size.
for index in selection:
selection_row = visible_rows.index(index.row())
selection_column = visible_columns.index(index.column())
model.setData(
model.index(index.row(), index.column()),
arr[selection_row][selection_column],
)
return
我们可以使用 self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
从 QTableView select 多个项目(部分行和部分列),但是在 selecting 一些行和列(部分和部分)之后,如果我这样做CTRL+C 并将其粘贴到记事本中它只粘贴一项(tableView 中的一个值)?
我的代码:
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.model.setSortRole(QtCore.Qt.UserRole)
self.tableView.setModel(self.model)
self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) '''this helps for selecting multiple items but not able to copy and paste multiple values to a text/ excel (it only copies single value)'''
我们如何复制和粘贴多个项目?
QAbstractItemView.ExtendedSelection 当用户以通常的方式选择一个项目时,选择被清除并选择新项目。但是,如果用户在单击某个项目时按下 Ctrl 键,则单击的项目会切换,所有其他项目将保持 不变 。如果用户在单击某个项目 的同时按下 Shift 键,则会选择或取消选择当前项目和所单击项目之间的所有项目,具体取决于所单击项目的状态。可以通过将鼠标拖到它们上面来选择多个项目。 你也可以使用
QAbstractItemView.MultiSelection
self.tableView.installEventFilters(self)
现在,添加事件过滤器:
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)
复制函数:
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())
非常感谢上面的@learncode 评论,我设法得到了复制部分。此外,我修改了一点以支持复制到 Excel 以及相应的单元格顺序:
def copySelection(self):
selection = self.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, delimiter='\t').writerows(table)
QtWidgets.qApp.clipboard().setText(stream.getvalue())
return
除了复制,我还创建了粘贴部分。根据用户选择的单元格范围(一个单元格或单元格范围),此代码段支持粘贴不同形状的数据。
def pasteSelection(self):
selection = self.selectedIndexes()
if selection:
model = self.model()
buffer = QtWidgets.qApp.clipboard().text()
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
reader = csv.reader(io.StringIO(buffer), delimiter='\t')
if len(rows) == 1 and len(columns) == 1:
for i, line in enumerate(reader):
for j, cell in enumerate(line):
model.setData(model.index(rows[0]+i,columns[0]+j), cell)
else:
arr = [ [ cell for cell in row ] for row in reader]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
model.setData(model.index(index.row(), index.column()), arr[row][column])
return
这个答案扩展了@learncode 和@Frederick Li 的答案以适应
的情况- 行列未按升序排列
- 视图中隐藏了某些行 and/or 列。
它还包括扩展事件过滤器以处理粘贴的代码。
class TableView(QTableView):
def __init__(self, *args, **kwargs):
super(TableView, self).__init__(*args, **kwargs)
self.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.KeyPress and event.matches(QKeySequence.Copy):
self.copy_selection()
return True
elif event.type() == QEvent.KeyPress and event.matches(QKeySequence.Paste):
self.paste_selection()
return True
return super(TableView, self).eventFilter(source, event)
def copy_selection(self):
selection = self.selectedIndexes()
if selection:
all_rows = []
all_columns = []
for index in selection:
if not index.row() in all_rows:
all_rows.append(index.row())
if not index.column() in all_columns:
all_columns.append(index.column())
visible_rows = [row for row in all_rows if not self.isRowHidden(row)]
visible_columns = [
col for col in all_columns if not self.isColumnHidden(col)
]
table = [[""] * len(visible_columns) for _ in range(len(visible_rows))]
for index in selection:
if index.row() in visible_rows and index.column() in visible_columns:
selection_row = visible_rows.index(index.row())
selection_column = visible_columns.index(index.column())
table[selection_row][selection_column] = index.data()
stream = io.StringIO()
csv.writer(stream, delimiter="\t").writerows(table)
QApplication.clipboard().setText(stream.getvalue())
def paste_selection(self):
selection = self.selectedIndexes()
if selection:
model = self.model()
buffer = QApplication.clipboard().text()
all_rows = []
all_columns = []
for index in selection:
if not index.row() in all_rows:
all_rows.append(index.row())
if not index.column() in all_columns:
all_columns.append(index.column())
visible_rows = [row for row in all_rows if not self.isRowHidden(row)]
visible_columns = [
col for col in all_columns if not self.isColumnHidden(col)
]
reader = csv.reader(io.StringIO(buffer), delimiter="\t")
arr = [[cell for cell in row] for row in reader]
if len(arr) > 0:
nrows = len(arr)
ncols = len(arr[0])
if len(visible_rows) == 1 and len(visible_columns) == 1:
# Only the top-left cell is highlighted.
for i in range(nrows):
insert_rows = [visible_rows[0]]
row = insert_rows[0] + 1
while len(insert_rows) < nrows:
row += 1
if not self.isRowHidden(row):
insert_rows.append(row)
for j in range(ncols):
insert_columns = [visible_columns[0]]
col = insert_columns[0] + 1
while len(insert_columns) < ncols:
col += 1
if not self.isColumnHidden(col):
insert_columns.append(col)
for i, insert_row in enumerate(insert_rows):
for j, insert_column in enumerate(insert_columns):
cell = arr[i][j]
model.setData(model.index(insert_row, insert_column), cell)
else:
# Assume the selection size matches the clipboard data size.
for index in selection:
selection_row = visible_rows.index(index.row())
selection_column = visible_columns.index(index.column())
model.setData(
model.index(index.row(), index.column()),
arr[selection_row][selection_column],
)
return