2016-07-24 84 views
2

所以我在Qt文檔中構建了books示例,我無法使用組合框進行編輯。基本上,我有一個QSqlRelationalTableModel映射到QTableView,並通過QDataWidgetMapper映射到其他幾個控件(其中一個是組合框)。表格視圖和映射器都使用默認的QSqlRelationalDelegate。默認的委託可以編輯,即使是外鍵的字段也可以編輯到其他表格中 - 它會在表格上創建一個組合框。爲什麼不用QComboBox,QDataWidgetMapper和QSqlRelationalTableModel編輯?

我可以在表格中編輯任何我想要的東西,而且工作得很好。我還可以使用通過小部件映射器映射的控件進行編輯,但組合框中的除外。組合框填充正確,當我在表中更改我的選擇時正確更新,但更改它的值對模型沒有影響。不過,直接在表中進行編輯(使用由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。

+1

原來,我需要組合框的currentIndexChanged()信號手動連接到數據控件映射器的提交()插槽。雖然我仍然不清楚爲什麼這對於組合框而不是其他控件是必需的...... – Garrett

+0

是否知道如果您[下載PyQt源代碼包](https)包含所有Qt示例的Python版本://www.riverbankcomputing.com/software/pyqt/download)?當然,自己製作它們可能仍然很有見地。 – titusjan

+1

我只是遇到了同樣的問題。我正在運行OS X,我相信問題的發生是因爲組合框沒有在OS X中獲得焦點,因此不會發出委託的commitData()信號。我的解決方法是'combobox.currentIndexChanged.connect(lambda:delegate.commitData.emit(combobox))'。 –

回答

0

非常感謝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)) 
相關問題