Question

J'ai QTableWidget avec des Cases à cocher dans certaines cellules.Je veux désactiver l'utilisateur afin d'effectuer un clic de souris sur les cellules de la table (donc il ne peut pas changer de case à cocher état) pour un certain temps alors que je suis en utilisant les données de la table.J'ai essayé table.setDisabled(1) mais qui désactive l'ensemble de la table et j'ai besoin de faire défiler jusqu'à être activé.

Toute aide serait appréciée.

MODIFIER Pour être plus précis:il pourrait y avoir jusqu'à 15x3000 cellules dans le tableau, rempli avec du texte(modifiable), case(vérifiables), svg graphiques(ouvre une autre fenêtre lors d'un double click sur celui-ci) ou de certains widgets personnalisés(qui ont également cliquables ou parties modifiables).J'ai besoin de désactiver l'utilisateur à cliquer ou double-cliquer sur les cellules(de sorte qu'il ne peut pas changer l'un d'eux) pour 1sec - 10sec intervalle de temps (la solution doit être quelque chose de rapide, pas d'une itération à travers tous les éléments), mais j'ai besoin de barre de défilement pour être activé et la table normale de la visibilité.

Était-ce utile?

La solution

Une façon d'y parvenir est de la sous-classe QTableWidgetItem et de re-mettre en œuvre les setData la méthode.De cette façon, vous pouvez contrôler si les éléments d'accepter des valeurs pour certains rôles.

Pour contrôler la "checkability" pour tous les éléments, vous pouvez ajouter un attribut de classe à la sous-classe qui pourrait être testé à chaque fois qu'une valeur pour le check-rôle de l'état a été adoptée à setData.

Voici ce que le sous-classe peut ressembler à:

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)

Et le "checkability" de tous les éléments seraient désactivés comme ceci:

    TableWidgetItem.setCheckable(False)

Mise à JOUR:

L'idée ci-dessus peut être étendu par l'ajout d'une classe wrapper générique pour la cellule de widgets.

Les classes ci-dessous permettra de bloquer les modifications de texte et de vérifier l'état de la table-widget articles, et aussi une gamme d'évènements souris et clavier pour la cellule de widgets via un événement-filtre (d'autres événements peuvent être bloqués si nécessaire).

La cellule-widgets devraient être créés comme ceci:

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

et alors accessible comme ceci:

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

Le blocage de l'ensemble de la table passerait comme ça:

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

Voici les catégories:

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)

Autres conseils

Juste itérer sur tous les QStandardItems et le changement valeurs d'indicateurs pour les articles qui ne doit pas être modifiable.
Vous pouvez utiliser le drapeau: Qt::ItemIsEditable ou/et Qt::ItemIsEnabled.

Vous devez désactiver les éléments eux-mêmes, par opposition à l'ensemble de la table si vous avez d'autres éléments que QCheckBoxes que vous ne souhaitez pas désactiver.Voir le code python ci-dessous pour plus de détails:

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

Ici vous pouvez trouver la documentation correspondante:

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

Définit les options pour l'élément à la donnée de drapeaux.Ces de déterminer si l'élément peut être sélectionné ou modifié.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top