Python 防止在StyledItemDelegate中编辑组合框

Python 防止在StyledItemDelegate中编辑组合框,python,pyqt,pyqt5,Python,Pyqt,Pyqt5,我试图使当前代码显示的所有内容都不可编辑 以前的搜索都建议修改模型的flags()函数或使用表的setEditTriggers。我在这段代码中都做了,但它们都不起作用 查看一个小部件一个小部件的情况,我可以找到LineEdit和其他小部件的只读模式,但不能找到ComboBox的只读模式。因此,我甚至不能修改委托以强制执行readonly约束,这并不是说我一定要这样做 编辑:澄清一下,当我说我希望用户不能“编辑”时,我的意思是他不能以任何方式更改小部件的状态。例如,他将无法单击组合框(或至少更改当

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

以前的搜索都建议修改模型的flags()函数或使用表的setEditTriggers。我在这段代码中都做了,但它们都不起作用

查看一个小部件一个小部件的情况,我可以找到LineEdit和其他小部件的只读模式,但不能找到ComboBox的只读模式。因此,我甚至不能修改委托以强制执行readonly约束,这并不是说我一定要这样做

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

从PyQt5导入QtCore、QtWidgets
导入系统
类MyWindow(QtWidgets.QWidget):
定义初始化(self,*args):
super()
tableview=tableview()
layout=qtwidts.QVBoxLayout(self)
layout.addWidget(tableview)
self.setLayout(布局)
类委托(QtWidgets.QStyledItemDelegate):
定义初始化(自我,模型):
super()。\uuuu init\uuuuu()
self.model=model
def createEditor(自身、父项、选项、索引):
widget=qtwidts.QComboBox(父项)
widget.addItems(['''Cat','Dog']))
返回小部件
def setModelData(自身、小部件、模型、索引):
self.model.setData(索引,widget.currentIndex())
类模型(QtCore.QAbstractTableModel):
def uuu init uuu(self,parent=None):
QtCore.QAbstractTableModel.\uuuuu init\uuuuu(self,parent=parent)
self.value=0
def标志(自、索引):
返回QtCore.Qt.ItemIsEnabled
def数据(self,index,role=QtCore.Qt.DisplayRole):
如果不是index.isValid()或role!=QtCore.Qt.DisplayRole:
返回QtCore.QVariant()
返回QtCore.QVariant(self.value)
def setData(self、index、value、role=QtCore.Qt.EditRole):
自我价值=价值
打印(“数据[{}][{}]={}.format(index.row(),index.column(),value))
返回真值
def行数(self,parent=QtCore.QModelIndex()):
返回1
def columnCount(self,parent=QtCore.QModelIndex()):
返回1
类TableView(QtWidgets.QTableView):
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
self.model=模型(self)
委托=委托(self.model)
self.setItemDelegate(委托)
self.setModel(self.model)
self.setEditTriggers(qtwidts.QTableWidget.NoEditTriggers)
对于范围内的行(self.model.rowCount()):
对于范围内的列(self.model.columnCount()):
index=self.model.index(行、列)
self.openpersisteneditor(索引)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app=qtwidts.QApplication(sys.argv)
w=MyWindow()
w、 show()
sys.exit(app.exec_())
说明: 必须澄清一些概念:

  • 对于Qt,禁用编辑一个视图(QListView、QTableView、QTreeView等)或视图项仅意味着编辑器不会通过单击、双击等用户事件打开

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

  • 用户通过操作系统与鼠标、键盘等进行交互
  • 操作系统将该交互通知给Qt
  • Qt创建s并将其发送到小部件
  • 小部件分析您应该修改的与您收到的信息有关的内容
在您的例子中,使用显示小部件,因此从Qt的角度来看,可食性在这种情况下是无效的

解决方案: 考虑到上述情况,一种可能的使小部件不可编辑的通用方法是:阻塞用户小部件交互路径的某个点。在这种情况下,最简单的方法是防止小部件通过事件过滤器接收消息

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

类DisableEventsManager(QtCore.QObject):
定义初始化(self,*,qobject,events=None,apply\u childrens=False):
如果不存在(qobject、QtCore.qobject):
提高打字错误(
f“{qobject}必须属于从qobject继承的类”
)
super()。\uuuu初始化(qobject)
self.\u qobject=qobject
self.\u events=事件或[]
self.\u qobject.installEventFilter(self)
self._children_filter=[]
如果适用于儿童:
对于self中的子对象。\u qobject.findChildren(qtwidts.QWidget):
子过滤器=禁用事件管理器(
qobject=child,events=events,apply\u childrens=apply\u childrens
)
self.\u children\u filter.append(children\u filter)
@财产
def事件(自):
返回自我。\u事件
@事件设置器
def事件(自身、事件):
self.\u事件=事件
对于self中的子过滤器。\u子过滤器:
child_filter.events=事件
def事件过滤器(自身、obj、事件):
如果self.events和self.\u qobject为obj:
如果self.events中的event.type():
返回真值
return super().eventFilter(对象,事件)

你能给我解释清楚吗?在QComboBox的情况下,你所说的“编辑”是什么意思?@eyllanesc我已经在主要帖子中添加了对你的提问的回复。正如你所说的,没有一个小部件是不可编辑的,它可能有不同的行为,这取决于小部件,在qcombobox的情况下,我理解它仅意味着涉及停用以下行为的所选项目不会改变:1)不处理箭头键,2)单击时,不应显示弹出窗口,是否存在其他情况?我是对的?我更改了标题,因为使小部件不可编辑过于宽泛,在QComboBox的情况下,它是有限的。@Eylandesc ComboBox只是一个例子。我只需要数据的只读视图,其中不使用普通的QTableView来显示,
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