2013-05-13 47 views
0

我遇到了一個問題,當用戶通過在Excel中選擇整個列進行復制時,從Excel中粘貼到QTableView中,基本上將選中列中的每一行都放入整個Excel表格中,在剪貼板上。以下是我的QTableView粘貼代碼(請注意,這是使用PyQt的Python,但原理與C++相同)。從Excel中將整列粘貼到QTableView中

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()發現此問題)。

是否有無論如何比剪切分隔文本或更多東西更有效地從剪貼板中獲取複製列?或者,當剪貼板上的字符串的大小是一些任意大的長度時,我應該拋出一個錯誤?

回答

0

不熟悉QTableView,但我在VBA Excel中有類似的經驗;顯然你打到了表格的底部。 Excel 97 - 2003中有65,536行,2007+中有1048576行,它不是任意的。

檢查行數,2個值中的任何一個都表示您剛剛通過整列而未碰到任何包含值的單元格,因此該列爲空。

+0

對不起,也許我沒有解釋好自己。突出顯示一個完全空的列僅僅是一個例子。如果所選列中的第一個單元格中包含單個字符,則從QClipboard獲取的PasteString的長度現在爲1048577,比第一個單元格中的值多1倍。 – user976640 2013-05-13 19:25:13

+0

好的,我誤解了這個問題;所以任何'pasteString.size()> = 1048576'都表示已經選擇了一個整列。那麼我會像解析數組一樣解析它,並丟棄相關區域上下的所有空容器; (在第一次和最後一次點擊內容之間);這應該很容易消除一百萬行 – 2013-05-14 16:05:01