禁用用户单击QTableWidget

时间:2014-01-08 16:25:54

标签: qt pyqt4 qtablewidget qcheckbox

我在某些单元格中有QTableWidget和CheckBoxes。我想禁用用户在表格单元格上执行鼠标点击(因此他无法更改checkBox状态)一段时间我正在使用表格中的数据。我已经尝试了table.setDisabled(1)但是禁用了整个表格,我需要滚动才能启用。

任何帮助都将不胜感激。

修改 更确切地说:表格中最多可以有15x3000个单元格,填充文本(可编辑),复选框(可检查),svg图形(双击时打开其他窗口)或一些自定义小部件(也可单击或可编辑)部分)。我需要禁用用户点击或双击单元格(所以他不能更改其中任何一个)1秒 - 10秒的时间间隔(解决方案必须快速,不要遍历所有项目),但我需要滚动条到启用和正常的表可见性。

3 个答案:

答案 0 :(得分:1)

实现此目的的一种方法是继承QTableWidgetItem并重新实现setData方法。这样,您就可以控制项目是否接受某些角色的值。

要控制所有项目的“可检查性”,您可以向子类添加一个class属性,只要将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)

<强>更新

可以通过为单元小部件添加通用包装类来扩展上述想法。

下面的类将阻止对表格小部件项目的文本和检查状态的更改,以及通过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)

答案 1 :(得分:0)

只需遍历所有QStandardItem并更改flags values以查找不可更改的项目。
您可以使用flag:Qt::ItemIsEditable或/和Qt::ItemIsEnabled

答案 2 :(得分:0)

如果您有其他项目而不是您不想禁用的QCheckBox,则需要禁用项目本身而不是整个表格。有关详细信息,请参阅下面的python代码:

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

     

将项目的标志设置为给定的标志。这些决定了是否可以选择或修改该项目。