2014-01-08 2 views
2

У меня QTableWidget с CheckBoxes в некоторых ячейках. Я хочу отключить пользователя для щелчка мыши над ячейками таблицы (так что он не может изменить состояние checkBox) некоторое время, пока я использую данные из таблицы. Я пробовал table.setDisabled(1), но это отключает всю таблицу, и мне нужно, чтобы прокрутка была включена.Отключить пользователя, чтобы щелкнуть QTableWidget

Любая помощь будет оценена по достоинству.

EDIT Чтобы быть более точным: там может быть до 15x3000 ячеек в таблице, заполненных текст (редактируемый), флажок (триггерный), SVG графике (открывает другое окно, когда дважды щелкните по нему) или некоторым пользовательскому виджеты (которые также имеют интерактивные или редактируемые части). Мне нужно отключить пользователя, чтобы щелкнуть или дважды щелкнуть по ячейкам (чтобы он не мог их изменить) в течение 1сек - интервал времени 10 с (решение должно быть чем-то быстрым, а не повторением всех элементов), но мне нужна строка прокрутки быть включенным и обычной видимостью таблицы.

ответ

1

Одним из способов достижения этого является подкласс 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) 
+0

hello, tnx для ответа. '@ classmethod' - это что-то новое, что я только что узнал (это похоже на' static' в C++, верно?), но я думаю, что не могу использовать его, потому что у меня много разных ячеек (с текстом, с checkBox, с svg graphic ...). или я могу? – Aleksandar

+1

@Aleksandar. Основное различие между '@ classmethod' и' @ staticmethod' в python заключается в том, что класс передается в качестве первого аргумента. Так как все экземпляры имеют один и тот же класс, он обеспечивает простой механизм совместного использования состояния (и, возможно, лучше, чем использование глобальной переменной). Что касается вашей реальной проблемы: я действительно задавался вопросом, используете ли вы виджеты для ячеек, что явно меняет спецификацию. Я вижу, вы отредактировали свой вопрос, но он все еще кажется underspecified. Что относительно действий клавиатуры? Должно ли все еще быть возможным выбирать ячейки, переходить из ячейки в ячейку с помощью клавиш со стрелками и т. Д. И т. Д.?? – ekhumoro

+0

@Aleksandar. Я обновил свой ответ с помощью решения, которое может сработать для вас. – ekhumoro

0

Просто переверните все QStandardItem с и измените flags values на предмет, который нельзя изменять.
Вы можете использовать флаг: Qt::ItemIsEditable или/и Qt::ItemIsEnabled.

+0

Чтобы быть точным, нет никаких Qt :: ItemsIsEditable и Qt :: ItemIEnabled в PyQt. – lpapp

0

Вам нужно будет отключить элементы самостоятельно, а не всю таблицу, если у вас есть другие элементы, кроме QCheckBoxes, которые вы не хотели бы отключать. Смотрите код питона подробности ниже:

''' 
    Iterate through all the check boxes in the standard items 
    and make sure the enabled flag is cleared so that the items are disabled 
''' 
for standardItem in standardItems: 
    standardItem.setFlags(standardItem.flags() & ~Qt.ItemIsEnabled) 

Здесь Вы можете найти соответствующую документацию:

void QTableWidgetItem::setFlags(Qt::ItemFlags flags)

Устанавливает флаги для элемента на заданных флагов. Они определяют, может ли элемент быть выбран или изменен.

+0

спасибо, что ответите. Сначала я подумал об этом, но моя таблица может содержать до 15x3000 ячеек, а время, когда я хочу отключить пользователя, чтобы выполнить клик, может быть 1 с - 10, поэтому повторение всех элементов может занять больше времени (это также необходимо включить). Вот почему мне нужно нечто большее, чем 'table.setDisabled (1)', но не влиять на прокрутку – Aleksandar

Смежные вопросы