Pergunta

Tenho QTableWidget com CheckBoxes em algumas células.Quero desabilitar o usuário para clicar com o mouse sobre as células da tabela (para que ele não possa alterar o estado da checkBox) por algum tempo enquanto estou usando os dados da tabela.eu tentei table.setDisabled(1) mas isso desativa a tabela inteira e preciso rolar para ativar.

Qualquer ajuda seria apreciada.

EDITARPara ser mais preciso:pode haver até 15x3000 células na tabela, preenchidas com texto (editável), caixa de seleção (verificável), gráfico SVG (abre outra janela ao clicar duas vezes nela) ou alguns widgets personalizados (que também possuem partes clicáveis ​​​​ou editáveis).Preciso desabilitar o usuário para clicar ou clicar duas vezes nas células (para que ele não possa alterar nenhuma delas) por um intervalo de tempo de 1 segundo a 10 segundos (a solução deve ser algo rápido, sem iterar por todos os itens), mas preciso da barra de rolagem para estar habilitado e com visibilidade normal da tabela.

Foi útil?

Solução

Uma maneira de conseguir isso é subclassificar QTableWidgetItem e reimplementar o definir dados método.Dessa forma, você pode controlar se os itens aceitam valores para determinadas funções.

Para controlar a "verificação" de todos os itens, você pode adicionar um atributo de classe à subclasse que pode ser testado sempre que um valor para a função de estado de verificação for passado para setData.

Esta é a aparência da subclasse:

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)

E a "verificação" de todos os itens seria desativada assim:

    TableWidgetItem.setCheckable(False)

ATUALIZAR:

A ideia acima pode ser estendida adicionando uma classe wrapper genérica para widgets de células.

As classes abaixo bloquearão alterações no texto e no estado de verificação para itens de widgets de tabela, e também uma série de eventos de teclado e mouse para widgets de células por meio de um filtro de eventos (outros eventos podem ser bloqueados conforme necessário).

Os widgets de célula precisariam ser criados assim:

    widget = CellWidget(self.table, QtGui.QLineEdit())
    self.table.setCellWidget(row, column, widget)

e então acessado assim:

    widget = self.table.cellWidget().widget()

O bloqueio para toda a tabela seria ativado assim:

    TableWidgetItem.setBlocked(True)
    CellWidget.setBlocked(True)
    # or Blockable.setBlocked(True)

Aqui estão as aulas:

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)

Outras dicas

Basta iterar por todos QStandardItemse mudar valores de sinalizadores para itens que não devem ser alteráveis.
Você pode usar sinalizador: Qt::ItemIsEditable ou e Qt::ItemIsEnabled.

Você precisaria desabilitar os próprios itens em vez de toda a tabela se tiver outros itens além de QCheckBoxes que não gostaria de desabilitar.Veja o código python abaixo para obter detalhes:

'''
    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)

Aqui você pode encontrar a documentação correspondente:

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

Define os sinalizadores do item para os sinalizadores fornecidos.Eles determinam se o item pode ser selecionado ou modificado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top