禁止用户点击 QTableWidget [英] Disable user to click over QTableWidget

查看:589
本文介绍了禁止用户点击 QTableWidget的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在某些单元格中有带有复选框的 QTableWidget.我想在我使用表格中的数据时禁止用户在表格单元格上执行鼠标单击(因此他无法更改复选框状态)一段时间.我试过 table.setDisabled(1) 但这会禁用整个表格,我需要启用滚动.

I have QTableWidget with CheckBoxes in some cells. I want to disable user to perform mouse click over the table cells (so he can't change checkBox state) for some time while I am using data from the table. I've tried table.setDisabled(1) but that disables whole table and I need scroll to be enabled.

任何帮助将不胜感激.

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

EDIT To be more precise: there could be up to 15x3000 cells in table, filled with text(editable), checkbox(checkable), svg graphic(opens other window when double click on it) or some custom widgets(which also have clickable or editable parts). I need to disable user to click or double click over cells(so he can't change any of them) for 1sec - 10sec time interval (solution must be something fast, not iterating through all items), but I need scroll-bar to be enabled and normal table visibility.

推荐答案

实现此目的的一种方法是将 QTableWidgetItem 子类化并重新实现 setData 方法.这样,您就可以控制项目是否接受特定角色的值.

One way to achieve this is to subclass QTableWidgetItem and re-implement the setData method. That way, you can control whether items accept values for certain roles.

要控制所有项目的可检查性",您可以向子类添加一个类属性,只要将检查状态角色的值传递给 setData,就可以测试该属性.

To control the "checkability" for all items, you could add a class attribute to the subclass which could be tested whenever a value for the check-state role was passed to 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)

并且所有项目的可检查性"将被禁用,如下所示:

And the "checkability" of all items would be disabled like this:

    TableWidgetItem.setCheckable(False)

更新:

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

The above idea can be extended by adding a generic wrapper class for cell widgets.

下面的类将通过 事件过滤器(可以根据需要阻止其他事件).

The classes below will block changes to text and check-state for table-widget items, and also a range of keyboard and mouse events for cell widgets via an event-filter (other events can be blocked as required).

需要像这样创建单元格小部件:

The cell-widgets would need to be created like this:

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

然后像这样访问:

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

整个表的阻塞将像这样打开:

Blocking for the whole table would be switched on like this:

    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)

这篇关于禁止用户点击 QTableWidget的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆