2016-11-23 143 views
1

我正在進行QAction,將剪貼板中的結構化文本粘貼到QTableWidget中。這是我當前的代碼:在QTableWidget中,如何確定空單元格是否可編輯?

class PasteCellsAction(qt.QAction): 
    def __init__(self, table): 
     if not isinstance(table, qt.QTableWidget): 
      raise ValueError('CopySelectedCellsAction must be initialised ' + 
          'with a QTableWidget.') 
     super(PasteCellsAction, self).__init__(table) 
     self.table = table 
     self.setText("Paste") 
     self.setShortcut(qt.QKeySequence('Ctrl+V')) 
     self.triggered.connect(self.pasteCellFromClipboard) 

    def pasteCellFromClipboard(self): 
     """Paste text from cipboard into the table. 

     If the text contains tabulations and 
     newlines, they are interpreted as column and row separators. 
     In such a case, the text is split into multiple texts to be paste 
     into multiple cells. 

     :return: *True* in case of success, *False* if pasting data failed. 
     """ 
     selected_idx = self.table.selectedIndexes() 
     if len(selected_idx) != 1: 
      msgBox = qt.QMessageBox(parent=self.table) 
      msgBox.setText("A single cell must be selected to paste data") 
      msgBox.exec_() 
      return False 

     selected_row = selected_idx[0].row() 
     selected_col = selected_idx[0].column() 

     qapp = qt.QApplication.instance() 
     clipboard_text = qapp.clipboard().text() 
     table_data = _parseTextAsTable(clipboard_text) 

     protected_cells = 0 
     out_of_range_cells = 0 

     # paste table data into cells, using selected cell as origin 
     for row in range(len(table_data)): 
      for col in range(len(table_data[row])): 
       if selected_row + row >= self.table.rowCount() or\ 
        selected_col + col >= self.table.columnCount(): 
        out_of_range_cells += 1 
        continue 
       item = self.table.item(selected_row + row, 
             selected_col + col) 
       # ignore empty strings 
       if table_data[row][col] != "": 
        if not item.flags() & qt.Qt.ItemIsEditable: 
         protected_cells += 1 
         continue 
        item.setText(table_data[row][col]) 

     if protected_cells or out_of_range_cells: 
      msgBox = qt.QMessageBox(parent=self.table) 
      msg = "Some data could not be inserted, " 
      msg += "due to out-of-range or write-protected cells." 
      msgBox.setText(msg) 
      msgBox.exec_() 
      return False 
     return True 

我想測試單元是否在其粘貼數據前可編輯的,爲此我使用QTableWidget.item(row, col)獲得該項目,然後我會檢查該項目的標誌。

我的問題是.item方法爲空單元返回None,所以我無法檢查空單元的標誌。我的代碼目前僅在粘貼區域中沒有空單元時起作用。

的錯誤是在線路46(None返回)和50(AttributeError: 'NoneType' object has no attribute 'flags'):

  item = self.table.item(selected_row + row, 
            selected_col + col) 
      # ignore empty strings 
      if table_data[row][col] != "": 
       if not item.flags() & qt.Qt.ItemIsEditable: 
        ... 

有沒有發現如果電池是可編輯的,不是檢查項目的標誌等的另一種方式?

+0

它返回'None'不是因爲單元格爲空,而是因爲單元格不存在 – Chr

+0

我不知道我理解這一點。我可以直觀地看到桌面小部件中的空單元格。你的意思是說,只要在單元格中沒有設置數據或標誌,它不會作爲一個項目存在? – PiRK

+0

如果答案是肯定的,是否可以編輯的單元格保證的不存在性?或者,我的小部件的用戶是否可以在不創建項目的情況下對其進行寫保護? – PiRK

回答

0

我發現了一個似乎可行的解決方案:創建一個新項目並在item()方法返回None時將其添加到表格中。

我仍然懷疑這是否有可能修改寫保護單元的標誌的風險。我目前假設如果一個單元格是寫保護的,這意味着它必須已經包含一個項目。

  item = self.table.item(target_row, 
            target_col) 
      # item may not exist for empty cells 
      if item is None: 
       item = qt.QTableWidgetItem() 
       self.table.setItem(target_row, 
            target_col, 
            item) 
      # ignore empty strings 
      if table_data[row_offset][col_offset] != "": 
       if not item.flags() & qt.Qt.ItemIsEditable: 
        protected_cells += 1 
        continue 
       item.setText(table_data[row_offset][col_offset]) 

編輯:target_row = selected_row + row_offset ...

3

沒有明確添加任何項目指定的QTableWidget罐尺寸。在這種情況下,這些單元格將完全變空 - 即數據和項目都將是None。如果用戶編輯單元格,則會將數據添加到表格的模型中,並添加一個項目。即使輸入的值是空字符串,也會發生這種情況。默認情況下,除非您採取明確的步驟將其設置爲只讀,否則所有單元格都可以編輯。

有很多方法可以使單元格爲只讀 - 例如,setting the edit triggers,或覆蓋表格的edit方法。但是,如果您的只有方法明確設置了各個表格 - 窗口小部件項目上的標誌,則可以安全地假定沒有項目的單元既可編輯又空白。 (請注意,如果您直接通過表格的模型設置數據而不是使用例如setItem,那麼該單元格將自動擁有一個項目)。

+0

我已經切換到通過模型獲取/設置數據而不是小部件,以便使我的操作能夠與QTableView以及QTableWidget一起使用。這消除了使用物品的需要。 – PiRK

相關問題