Одним из способов достижения этого является подкласс QTableWidgetItem и повторная реализация метода setData. Таким образом, вы можете контролировать, принимают ли элементы значения для определенных ролей.
Чтобы контролировать «проверку» для всех элементов, вы можете добавить атрибут класса к подклассу, который может быть проверен всякий раз, когда значение для функции check-state было передано в setData.
Вот что подкласс может выглядеть следующим образом:
class TableWidgetItem(QtGui.QTableWidgetItem):
_blocked = True
@classmethod
def blocked(cls):
return cls._checkable
@classmethod
def setBlocked(cls, checkable):
cls._checkable = bool(checkable)
def setData(self, role, value):
if role != QtCore.Qt.CheckStateRole or self.checkable():
QtGui.QTableWidgetItem.setData(self, role, value)
и "проверяемость" всех элементов будут отключены, как это:
TableWidgetItem.setCheckable(False)
UPDATE:
выше идея может быть расширена путем добавления общего класса оболочки для виджетов ячеек.
В приведенных ниже классах будут блокированы изменения текста и состояния проверки элементов таблицы-виджета, а также диапазон событий клавиатуры и мыши для виджетов ячеек через event-filter (при необходимости могут быть заблокированы другие события).
Клеточные-виджеты должны быть созданы таким образом:
widget = CellWidget(self.table, QtGui.QLineEdit())
self.table.setCellWidget(row, column, widget)
, а затем обращались так:
widget = self.table.cellWidget().widget()
Блокировка для всей таблицы будет включен следующим образом:
TableWidgetItem.setBlocked(True)
CellWidget.setBlocked(True)
# or Blockable.setBlocked(True)
Ниже перечислены следующие классы:
class Blockable(object):
_blocked = False
@classmethod
def blocked(cls):
return cls._blocked
@classmethod
def setBlocked(cls, blocked):
cls._blocked = bool(blocked)
class TableWidgetItem(Blockable, QtGui.QTableWidgetItem):
def setData(self, role, value):
if (not self.blocked() or (
role != QtCore.Qt.EditRole and
role != QtCore.Qt.CheckStateRole)):
QtGui.QTableWidgetItem.setData(self, role, value)
class CellWidget(Blockable, QtGui.QWidget):
def __init__(self, parent, widget):
QtGui.QWidget.__init__(self, parent)
self._widget = widget
layout = QtGui.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(widget)
widget.setParent(self)
widget.installEventFilter(self)
if hasattr(widget, 'viewport'):
widget.viewport().installEventFilter(self)
widget.show()
def widget(self):
return self._widget
def eventFilter(self, widget, event):
if self.blocked():
etype = event.type()
if (etype == QtCore.QEvent.KeyPress or
etype == QtCore.QEvent.KeyRelease or
etype == QtCore.QEvent.MouseButtonPress or
etype == QtCore.QEvent.MouseButtonRelease or
etype == QtCore.QEvent.MouseButtonDblClick or
etype == QtCore.QEvent.ContextMenu or
etype == QtCore.QEvent.Wheel):
return True
return QtGui.QWidget.eventFilter(self, widget, event)
hello, tnx для ответа. '@ classmethod' - это что-то новое, что я только что узнал (это похоже на' static' в C++, верно?), но я думаю, что не могу использовать его, потому что у меня много разных ячеек (с текстом, с checkBox, с svg graphic ...). или я могу? – Aleksandar
@Aleksandar. Основное различие между '@ classmethod' и' @ staticmethod' в python заключается в том, что класс передается в качестве первого аргумента. Так как все экземпляры имеют один и тот же класс, он обеспечивает простой механизм совместного использования состояния (и, возможно, лучше, чем использование глобальной переменной). Что касается вашей реальной проблемы: я действительно задавался вопросом, используете ли вы виджеты для ячеек, что явно меняет спецификацию. Я вижу, вы отредактировали свой вопрос, но он все еще кажется underspecified. Что относительно действий клавиатуры? Должно ли все еще быть возможным выбирать ячейки, переходить из ячейки в ячейку с помощью клавиш со стрелками и т. Д. И т. Д.?? – ekhumoro
@Aleksandar. Я обновил свой ответ с помощью решения, которое может сработать для вас. – ekhumoro