为什么不编辑QComboBox,QDataWidgetMapper和QSqlRelationalTableModel?

问题描述 投票:2回答:2

所以我在Qt文档中构建了books示例,我无法使用组合框进行编辑。基本上,我有一个QSqlRelationalTableModel映射到QTableView,并通过QDataWidgetMapper映射到其他几个控件(其中一个是组合框)。表视图和映射器都使用默认的QSqlRelationalDelegate。默认委托允许编辑,即使对于作为其他表的外键的字段 - 它也会在表上创建一个组合框。

我可以在表格中编辑我想要的任何内容,它可以正常工作。我还可以使用通过小部件映射器映射的控件进行编辑,但组合框除外。组合框正确填充,并在我更改表中的选择时正确更新,但更改它的值对模型没有影响。但是直接在表中进行编辑(使用QSqlRelationalDelegate创建的组合框)确实有效。

从阅读示例和文档,似乎这应该工作。我甚至尝试过实现自定义委托,但是在对组合框进行更改时,它的setModelData()方法甚至都不会被调用(为什么不呢?)。

有没有其他人有这个问题?你是怎么解决的?我觉得我必须遗漏一些明显的东西。以下代码的相关部分:

# Create the model
self.model = QSqlRelationTableModel(self.tableView)
self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
self.model.setTable('products')

categoryIdx = self.model.fieldIndex('category')

# Set the relation for the category field
self.model.setRelation(categoryIdx, QSqlRelation('categories', 'id', 'name'))

# Populate the model
self.model.select()

# Connect the model and the table
self.tableView.setModel(self.model)
self.tableView.setItemDelegate(QSqlRelationalDelegate(self))

# Set up the controls
self.categoryBox.setModel(self.model.relationModel(categoryIdx))
self.categoryBox.setModelColumn(self.model.relationModel(categoryIdx).fieldIndex('name')

mapper = QDataWidgetMapper(self)
mapper.setModel(self.model)
mapper.setItemDelegate(QSqlRelationalDelegate(self))
mapper.addMapping(self.categoryBox, categoryIdx)
... # Add mappings to the other controls
mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit)

self.tableView.selectionModel().currentRowChanged.connect(mapper.setCurrentModelIndex)

我甚至试过像这样指定currentIndex属性:

mapper.addMapping(self.categoryBox, categoryIdx, 'currentIndex')

但这也不起作用。我正在使用PyQt5,FWIW。

python qt pyqt
2个回答
1
投票

非常感谢Garrett和GeorgSchölly的这些帖子!我也遇到了同样的问题,可以用你的答案来解决它。在我的情况下,我做了一个QDataWidgetMapper子类,自动进行所需的信号槽连接:

class DataWidgetMapper(QDataWidgetMapper):
    def addMapping(self, widget, section, propertyName=None):
        if propertyName is None:
            super().addMapping(widget, section)
        else:
            super().addMapping(widget, section, propertyName)

        if isinstance(widget, QComboBox):
            delegate = self.itemDelegate()
            widget.currentIndexChanged.connect(lambda: delegate.commitData.emit(widget))

0
投票

将QComboBox focusPolicy设置为ClickFocus或StrongFocus(Qt Designer或代码中)

widget.setFocusPolicy(Qt.StrongFocus)
© www.soinside.com 2019 - 2024. All rights reserved.