当用户通过在 Excel 中选择一整列进行复制时,我在从 Excel 粘贴到 QTableView 时遇到问题,本质上是将所选列中的每一行都放在剪贴板上,用于整个 Excel 工作表。以下是我的 QTableView 粘贴代码(请注意,这是在 Python 中使用 PyQt 但原理与 C++ 相同)。
def paste(self):
model=self.model()
pasteString=QtGui.QApplication.clipboard().text()
rows=pasteString.split('\n')
numRows=len(rows)
numCols=rows[0].count('\t')+1
selectionRanges=self.selectionModel().selection()
#make sure we only have one selection range and not non-contiguous selections
if len(selectionRanges)==1:
topLeftIndex=selectionRanges[0].topLeft()
selColumn=topLeftIndex.column()
selRow=topLeftIndex.row()
if selColumn+numCols>model.columnCount():
#the number of columns we have to paste, starting at the selected cell, go beyond how many columns exist.
#insert the amount of columns we need to accomodate the paste
model.insertColumns(model.columnCount(), numCols-(model.columnCount()-selColumn))
if selRow+numRows>model.rowCount():
#the number of rows we have to paste, starting at the selected cell, go beyond how many rows exist.
#insert the amount of rows we need to accomodate the paste
model.insertRows(model.rowCount(), numRows-(model.rowCount()-selRow))
#block signals so that the "dataChanged" signal from setData doesn't update the view for every cell we set
model.blockSignals(True)
for row in xrange(numRows):
columns=rows[row].split('\t')
[model.setData(model.createIndex(selRow+row, selColumn+col), QVariant(columns[col])) for col in xrange(len(columns))]
#unblock the signal and emit dataChangesd ourselves to update all the view at once
model.blockSignals(False)
model.dataChanged.emit(topLeftIndex, model.createIndex(selRow+numRows, selColumn+numCols))
当用户在 Excel 中选择了一堆单元格并复制了这些单元格时,这一切都很好。当他们选择一整列时它会崩溃,因为它pasteString
的长度超过 1048576 个字符(通过选择其标题并复制突出显示一个完全空的 Excel 列时打印 pasteString.size() 可以找到)。
无论如何,从剪贴板中获取复制的列是否比制表符分隔的文本或其他内容更有效?或者当剪贴板上的字符串长度任意大时,我应该抛出一个错误吗?