我正在进行QAction,将剪贴板中的结构化文本粘贴到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 :(得分:3)
可以指定QTableWidget
a的尺寸,而无需明确添加任何项目。在这种情况下,单元格将完全为空 - 即数据和项目都将是None
。如果用户编辑单元格,则数据将添加到表格模型中,并添加一个项目。即使输入的值是空字符串,也会发生这种情况。默认情况下,除非您采取明确的步骤将它们设置为只读,否则所有单元格都是可编辑的。
有许多方法可以将单元格设置为只读 - 例如setting the edit triggers,或覆盖表格的edit方法。但是,如果 only 方法明确设置单个表窗口小部件项目上的标记,则可以安全地假设没有项目的单元格既可编辑又为空。 (请注意,如果您通过表格模型直接设置数据而不是使用例如setItem
,则单元格仍将自动拥有一个项目。)
答案 1 :(得分: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
...