从QDataWidgetMapper获得2个组合框的工作。

问题描述 投票:0回答:1

请好心。 这是我的第一个问题。 我已经附上了一个最小的列表,说明了这个问题。

from PyQt5 import QtWidgets, QtCore, QtGui, uic, QtSql
from PyQt5.QtCore import Qt
qtCreatorFile = "QuotesGui.ui" 

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

class QuotesUI(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, model):
        QtWidgets.QMainWindow.__init__(self)
        uic.loadUi(qtCreatorFile,self)
        self.setupUi(self)
        self.model = model # View owns the model    


        self.tableView.setModel(self.model._formModel)

        self.setWidgetMapping() # Map model to view widgets

        authorSRD = QtSql.QSqlRelationalDelegate(self.authorComboBox)
        self.authorComboBox.setModel(self.model._authorModel)
        self.authorComboBox.setItemDelegate(authorSRD)
        self.authorComboBox.setModelColumn(
        self.model._formModel.fieldIndex("authorName"))

        citationSRD = QtSql.QSqlRelationalDelegate(self.citationComboBox)
        self.citationComboBox.setModel(self.model._citationModel)
        self.citationComboBox.setItemDelegate(citationSRD)
        self.citationComboBox.setModelColumn(
        self.model._formModel.fieldIndex("citationText"))

        self.mainMapper.toFirst()
        self._updateButtons(0) # To disable the previous button at start up
        self.saveBtn.setEnabled(False) # Since we can't edit, we can't save


        self._connectSignals(self.model)



    def setWidgetMapping(self):
        self.mainMapper = QtWidgets.QDataWidgetMapper(self)
        self.mainMapper.setModel(self.model._formModel)
        self.mainMapper.setItemDelegate(QtSql.QSqlRelationalDelegate(self))
        self.mainMapper.addMapping(self.authorComboBox,
            self.model._formModel.fieldIndex("authorName"))
        self.mainMapper.addMapping(self.citationComboBox,
            self.model._formModel.fieldIndex("citationText"))
        self.mainMapper.addMapping(self.quoteText,
            self.model._formModel.fieldIndex("quoteText"))


    def _connectSignals(self, model):
        self.lastBtn.clicked.connect(self.mainMapper.toLast)
        self.nextBtn.clicked.connect(self.mainMapper.toNext)
        self.prevBtn.clicked.connect(self.mainMapper.toPrevious)
        self.firstBtn.clicked.connect(self.mainMapper.toFirst)
        self.mainMapper.currentIndexChanged.connect(
            self._updateButtons)




    def _updateButtons(self, row):
        self.firstBtn.setEnabled(row > 0)
        self.prevBtn.setEnabled(row > 0)
        self.nextBtn.setEnabled(row < self.model._formModel.rowCount() - 1)
        self.lastBtn.setEnabled(row < self.model._formModel.rowCount() - 1)


class QuoteModel():
    def __init__(self, data):
        # Make a database connection
        self.db = self.createConnection(data)

        # set models
        self._setFormModel()
        self._setAuthorComboTableLink()
        self._setCitationComboTableLink()   

        # Connect signals
        self._connectSignals()

    # Define a model for the form
    def _setFormModel(self):
        self._formModel = QtSql.QSqlRelationalTableModel(
            parent = None, db = self.db)
        self._formModel.setEditStrategy(
            QtSql.QSqlTableModel.OnManualSubmit)
        self._formModel.setTable("Quote")
        authorIdx = self._formModel.fieldIndex("authorId")
        citationIdx = self._formModel.fieldIndex("citationId")
        self._formModel.setJoinMode(1) # Left Join
        self._formModel.setRelation(authorIdx, QtSql.QSqlRelation(
            "Author", "authorId", "authorName"))
        self._formModel.setRelation(citationIdx, QtSql.QSqlRelation(
            "Citation", "citationId", "citationText"))
        self._formModel.select()


     # Define models and link tables for the two comboboxes
     def _setAuthorComboTableLink(self):
        self._authorModel = QtSql.QSqlTableModel(
            parent = None, db =   self.db)
        self._authorModel.setTable("Author")
        self._authorModel.setEditStrategy(
            QtSql.QSqlTableModel.OnManualSubmit)
        self._authorModel.select()
        self._authorModel.sort(1,Qt.AscendingOrder) 

    def _setCitationComboTableLink(self):
        self._citationModel = QtSql.QSqlTableModel(
            parent = None, db = self.db)
        self._citationModel.setTable("Citation")
        self._citationModel.setEditStrategy(
            QtSql.QSqlTableModel.OnManualSubmit)
        self._citationModel.select()
        self._citationModel.sort(1,Qt.AscendingOrder)   

    def _newData(self):
        print('in _newData')

    def _connectSignals(self):
        self._authorModel.rowsInserted.connect(self._newData)


#######################################################     
    # A function to connect to a named database
    def createConnection(self,dbfile):
        db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName(dbfile)
        db.open()

        if not db.open():
            QtWidgets.QMessageBox.critical(
            None, QtWidgets.qApp.tr("Cannot open database"),
            QtWidgets.qApp.tr("Unable to establish a database   connection.\n"),
            QtWidgets.QMessageBox.Cancel,
            )
            return False

        return db

dbFile = "Quotations.db"

if __name__=='__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)

    m = QuoteModel(dbFile)

    w = QuotesUI(m)
    w.show()

    sys.exit(app.exec_())

还是需要上传一个8kb的.ui文件和一个70kb的样本数据库才能运行。 到目前为止,我还没能弄清楚如何做到这一点......

当运行这个程序时,结合其他必要的代码,作者组合框就像预期的那样工作,即:下拉菜单显示了作者表中的所有值,当我在模型中踩踏记录时,正确的作者就会显示在组合框中。

引用组合框不工作。 就像这里写的那样,它既不显示引文表的值,也不连接到引文表。 基本上它什么都不显示。

我想我需要,以某种方式,在模型上建立第二个委托。 但我不知道怎么做。

有什么办法能让这个功能发挥作用吗?

python database combobox pyqt
1个回答
0
投票

为了让这个工作正常进行,我不得不将

self.authorComboBox.setModel(self.model._authorModel)

改为:

authorRel = self.model._formModel.relationModel(self.model.authorIdx)
self.authorComboBox.setModel(authorRel)

QSqlRelationalTableModel有一个虚拟函数 "relationModel",可以返回一个QSqlTableModel。 当你使用这个模型作为QComboBox的模型时,一切都能正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.