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

答えがYESの場合、セルの存在が保証されているかどうかは編集可能ですか?または、私のウィジェットのユーザーが項目を作成せずに書き込み禁止にすることができますか? – 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]) 

EDIT:target_row = selected_row + row_offset ...

3

QTableWidgetの寸法明示的に任意の項目を追加することなく、指定することができます。この場合、セルは完全に空になります。つまり、データと項目の両方がNoneになります。ユーザーがセルを編集すると、データが表のモデルに追加され、項目が追加されます。これは、入力された値が空の文字列であっても発生します。既定では、明示的な手順を実行して読み取り専用にしない限り、すべてのセルが編集可能になります。

たとえば、setting the edit triggersなどのセルを読み取り専用にする方法や、テーブルのeditメソッドを上書きする方法が数多くあります。しかし、メソッドだけが、個々のテーブルウィジェットアイテムにフラグを明示的に設定している場合は、アイテムのないセルが編集可能で空であると見なすことができます。 (たとえば、setItemなどを使用するのではなく、表のモデルを介してデータを直接設定した場合でも、セルには自動的に項目があります)。

+0

QTableViewとQTableWidgetで動作するように、ウィジェットではなくモデルを介してデータを取得/設定するように切り替えました。これにより、アイテムを扱う必要がなくなります。 – PiRK

関連する問題