禁止用户点击 QTableWidget
-
20-12-2019 - |
题
我在某些单元格中有带有复选框的 QTableWidget。当我使用表中的数据时,我想禁止用户在表单元格上执行鼠标单击(这样他就无法更改复选框状态)一段时间。我试过了 table.setDisabled(1)
但这会禁用整个表格,我需要启用滚动。
任何帮助,将不胜感激。
编辑更准确地说:表格中最多可以有 15x3000 个单元格,填充文本(可编辑)、复选框(可选中)、svg 图形(双击时打开其他窗口)或一些自定义小部件(也有可单击或可编辑部分)。我需要禁止用户在 1 秒 - 10 秒的时间间隔内单击或双击单元格(这样他就无法更改任何单元格)(解决方案必须是快速的,而不是迭代所有项目),但我需要滚动条启用并正常表可见性。
解决方案
实现此目的的一种方法是子类化 QTableWidgetItem 并重新实现 设置数据 方法。这样,您可以控制项目是否接受某些角色的值。
要控制所有项目的“可检查性”,您可以向子类添加一个类属性,每当将检查状态角色的值传递给 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)
更新:
可以通过为单元格小部件添加通用包装类来扩展上述想法。
下面的类将阻止对表格小部件项目的文本和检查状态的更改,以及通过以下方式阻止单元格小部件的一系列键盘和鼠标事件: 事件过滤器 (可以根据需要阻止其他事件)。
单元格小部件需要像这样创建:
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)
其他提示
只需迭代所有 QStandardItem
和改变 标志值 对于不应该改变的项目。
您可以使用标志: Qt::ItemIsEditable
或/和 Qt::ItemIsEnabled
.
如果您不想禁用 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 标志)
将项目的标志设置为给定的标志。这些决定是否可以选择或修改该项目。