В QTableWidget, как определить, является ли пустая ячейка редактируемой?
Я работаю над 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:
...
Есть ли другой способ узнать, является ли ячейка редактируемой, кроме проверки флагов элемента?
2 ответа
Размеры QTableWidget
может указывать без явного добавления каких-либо элементов. В этом случае ячейки будут полностью пустыми - т.е. и данные, и элемент будут None
, Если пользователь редактирует ячейку, данные будут добавлены в модель таблицы, и будет добавлен элемент. Это произойдет, даже если введенное значение является пустой строкой. По умолчанию все ячейки будут доступны для редактирования, если вы не предпримете явных шагов, чтобы сделать их доступными только для чтения.
Существует множество способов сделать ячейки доступными только для чтения - например, установить триггеры редактирования или переопределить метод редактирования таблиц. Но если ваш единственный метод явно устанавливает флаги для отдельных элементов таблицы-виджета, вы можете смело предполагать, что ячейка без элемента является редактируемой и пустой. (Обратите внимание, что если вы устанавливаете данные напрямую через модель таблицы, а не с помощью, например, setItem
ячейка все равно будет автоматически иметь элемент).
Я нашел решение, которое, кажется, работает: создайте новый элемент и добавьте его в таблицу, когда 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
...