请好心。 这是我的第一个问题。 我已经附上了一个最小的列表,说明了这个问题。
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的样本数据库才能运行。 到目前为止,我还没能弄清楚如何做到这一点......
当运行这个程序时,结合其他必要的代码,作者组合框就像预期的那样工作,即:下拉菜单显示了作者表中的所有值,当我在模型中踩踏记录时,正确的作者就会显示在组合框中。
引用组合框不工作。 就像这里写的那样,它既不显示引文表的值,也不连接到引文表。 基本上它什么都不显示。
我想我需要,以某种方式,在模型上建立第二个委托。 但我不知道怎么做。
有什么办法能让这个功能发挥作用吗?
为了让这个工作正常进行,我不得不将
self.authorComboBox.setModel(self.model._authorModel)
改为:
authorRel = self.model._formModel.relationModel(self.model.authorIdx)
self.authorComboBox.setModel(authorRel)
QSqlRelationalTableModel有一个虚拟函数 "relationModel",可以返回一个QSqlTableModel。 当你使用这个模型作为QComboBox的模型时,一切都能正常工作。