【问题标题】:Paste entire column into QTableView from Excel将整个列从 Excel 粘贴到 QTableView
【发布时间】:2013-05-07 22:03:35
【问题描述】:

当用户通过在 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() 可以找到)。

有没有比制表符分隔的文本更有效地从剪贴板获取复制的列?还是当剪贴板上的字符串长度任意大时,我应该抛出一个错误?

【问题讨论】:

    标签: excel qt pyqt paste qtableview


    【解决方案1】:

    不熟悉QTableView,但我在VBA Excel中有类似的经验;显然你打到了表格的底部。 Excel 97 - 2003 有 65,536 行,2007+ 有 1048576 行,这不是任意的。

    检查行数,这两个值中的任何一个都表明您刚刚浏览了整个列而没有点击任何包含值的单元格,因此该列是空的。

    【讨论】:

    • 抱歉,可能我解释得不好。突出显示一个完全空的列只是一个例子。如果所选列中的第一个单元格中包含单个字符,则从 QClipboard 中抓取的 pasteString 的长度现在为 1048577,由于第一个单元格中的值,比以前增加了 +1。
    • 好的,我误解了这个问题;所以任何pasteString.size() >= 1048576 表示已选择一整列。然后我会像数组一样解析它并丢弃相关区域上方和下方的所有空物; (在内容的第一次和最后一次点击之间);这应该很容易消除一百万行
    猜你喜欢
    • 2016-11-13
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    相关资源
    最近更新 更多