2016-11-23 97 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

相关问题