gpt4 book ai didi

python - 防止在 QStyledItemDelegate 中编辑 ComboBox

转载 作者:行者123 更新时间:2023-12-01 07:10:26 25 4
gpt4 key购买 nike

我试图使当前代码显示的所有内容都不可编辑。

之前的搜索都建议要么修改模型的flags()函数,要么使用表的setEditTriggers。我在这段代码中同时执行了这两项操作,但它们都不起作用。

查看逐个小部件的情况,我可以找到 LineEdit 和其他部件的只读模式,但不能找到 ComboBox 的只读模式。所以我什至无法修改委托(delegate)来强制只读约束,并不是说我一定想这样做。

编辑:澄清一下,当我说我希望用户无法“编辑”时,我的意思是他不应该能够以任何方式更改小部件的状态。例如。他将无法单击组合框(或至少更改当前选定的项目/索引)。

from PyQt5 import QtCore, QtWidgets
import sys


class MyWindow(QtWidgets.QWidget):
def __init__(self, *args):
super().__init__(*args)
tableview = TableView()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(tableview)
self.setLayout(layout)


class Delegate(QtWidgets.QStyledItemDelegate):
def __init__(self, model):
super().__init__()
self.model = model

def createEditor(self, parent, option, index):
widget = QtWidgets.QComboBox(parent)
widget.addItems(['', 'Cat', 'Dog'])
return widget

def setModelData(self, widget, model, index):
self.model.setData(index, widget.currentIndex())


class Model(QtCore.QAbstractTableModel):
def __init__(self, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent=parent)
self.value = 0

def flags(self, index):
return QtCore.Qt.ItemIsEnabled

def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid() or role != QtCore.Qt.DisplayRole:
return QtCore.QVariant()
return QtCore.QVariant(self.value)

def setData(self, index, value, role=QtCore.Qt.EditRole):
self.value = value
print("data[{}][{}] = {}".format(index.row(), index.column(), value))
return True

def rowCount(self, parent=QtCore.QModelIndex()):
return 1

def columnCount(self, parent=QtCore.QModelIndex()):
return 1


class TableView(QtWidgets.QTableView):
def __init__(self, parent=None):
super().__init__(parent)
self.model = Model(self)
delegate = Delegate(self.model)
self.setItemDelegate(delegate)
self.setModel(self.model)
self.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
for row in range(self.model.rowCount()):
for column in range(self.model.columnCount()):
index = self.model.index(row, column)
self.openPersistentEditor(index)


if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())

最佳答案

说明:

必须澄清一些概念:

  • 对于 Qt 来说,禁用 View (QListView、QTableView、QTreeView 等)或 View 项的编辑仅意味着编辑器不会通过用户事件(例如单击、双击等)打开。

  • Qt 中的用户交互遵循以下路径:

    1. 用户通过操作系统使用鼠标、键盘等进行交互。
    2. 操作系统会通知 Qt 该交互。
    3. Qt 创建 QEvent s 并将其发送到小部件。
    4. 该小部件会分析您应针对 QEvent 进行修改的内容您收到了。

就您而言,使用 openPersistentEditor()显示小部件,因此从 Qt 的角度来看,可食用性对于这种情况无效。

解决方案:

考虑到上述可能是使小部件不可编辑的通用方法:阻止用户小部件交互路径的某些点。在这种情况下,最简单的事情就是阻止小部件接收 QEvent通过事件过滤器。

考虑到上述情况,解决方案是:

class DisableEventsManager(QtCore.QObject):
def __init__(self, *, qobject, events=None, apply_childrens=False):
if not isinstance(qobject, QtCore.QObject):
raise TypeError(
f"{qobject} must belong to a class that inherits from QObject"
)
super().__init__(qobject)

self._qobject = qobject
self._events = events or []

self._qobject.installEventFilter(self)
self._children_filter = []
if apply_childrens:
for child in self._qobject.findChildren(QtWidgets.QWidget):
child_filter = DisableEventsManager(
qobject=child, events=events, apply_childrens=apply_childrens
)
self._children_filter.append(child_filter)

@property
def events(self):
return self._events

@events.setter
def events(self, events):
self._events = events
for child_filter in self._children_filter:
child_filter.events = events

def eventFilter(self, obj, event):
if self.events and self._qobject is obj:
if event.type() in self.events:
return True
return super().eventFilter(obj, event)
def createEditor(self, parent, option, index):
combo = QtWidgets.QComboBox(parent)
combo.addItems(["", "Cat", "Dog"])
combo_event_filter = DisableEventsManager(qobject=combo)
combo_event_filter.events = [
QtCore.QEvent.KeyPress,
QtCore.QEvent.FocusIn,
QtCore.QEvent.MouseButtonPress,
QtCore.QEvent.MouseButtonDblClick,
]
return combo

关于python - 防止在 QStyledItemDelegate 中编辑 ComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58250309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com