【问题标题】:Why doesn't editing work with QComboBox, QDataWidgetMapper, and QSqlRelationalTableModel?为什么 QComboBox、QDataWidgetMapper 和 QSqlRelationalTableModel 无法进行编辑?
【发布时间】:2016-11-27 14:28:23
【问题描述】:

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

我可以在表格中编辑任何我想要的东西,而且效果很好。我还可以使用通过小部件映射器映射的控件进行编辑,except 和组合框。当我在表中更改我的选择时,组合框会正确填充并正确更新,但更改它的值对模型没有影响。但是直接在表中进行编辑(使用由 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。

【问题讨论】:

  • 原来我需要手动将组合框的 currentIndexChanged() 信号连接到数据小部件映射器的 submit() 插槽。虽然我仍然不清楚为什么这对于组合框而不是其他控件是必要的......
  • 如果您download the source package of PyQt,您是否知道所有Qt示例的python版本都包含在内?当然,自己制作可能仍然很有见地。
  • 我也遇到了同样的问题。我正在运行 OS X,我相信问题的发生是因为组合框没有在 OS X 中获得焦点,因此不会发出代表的 commitData() 信号。我的解决方法是combobox.currentIndexChanged.connect(lambda: delegate.commitData.emit(combobox))

标签: python qt pyqt


【解决方案1】:

非常感谢 Garrett 和 Georg Schö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))

【讨论】:

    【解决方案2】:

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

    widget.setFocusPolicy(Qt.StrongFocus)
    

    【讨论】:

      猜你喜欢
      • 2013-04-11
      • 2017-01-07
      • 1970-01-01
      • 2013-09-15
      • 2018-03-05
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 2019-10-03
      相关资源
      最近更新 更多