在 PyQt 中,我尝试允许用户选择要打开的数据库,每个数据库都有相同的模式。然而,在打开数据库后,我无法让 QTableView 填充数据。
下面是代码示例:
class aMainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName('testdb.db')
self.db.open()
# Set up the user interface from Designer.
self.setupUi(self)
#self.db.setDatabaseName('testdb.db')
self.model = QSqlTableModel(self)
self.model.setTable("records")
self.model.setSort(FILEORDER, Qt.AscendingOrder)
self.model.setHeaderData(ID, Qt.Horizontal, QVariant("ID"))
self.model.setHeaderData(FILEORDER, Qt.Horizontal, QVariant("File Order"))
self.model.setHeaderData(RECORDTYPE, Qt.Horizontal, QVariant("Type"))
self.model.setHeaderData(NAME, Qt.Horizontal, QVariant("Name"))
self.model.setHeaderData(PRESORTNAME, Qt.Horizontal, QVariant("Presort Name"))
self.model.setHeaderData(RECORD, Qt.Horizontal, QVariant("Record"))
self.model.select()
self.tableView.setModel(self.model)
#self.view.setSelectionMode(QTableView.SingleSelection)
#self.view.setSelectionBehavior(QTableView.SelectRows)
self.tableView.setColumnHidden(ID, True)
self.tableView.setColumnHidden(PRESORTNAME, True)
self.tableView.setColumnHidden(RECORD, True)
当数据库名称为 testdb.db 时,代码可以正常工作,但如果通过文件选择对话框选择其他数据库,则 QTableView 无法填充数据。
2、解决方案
根据一个论坛帖子的提示,发现连接必须在创建模型之前进行,因为模型构造中可能会接触到数据库。因此,将 on_actionOpen_DB_triggered 函数修改为在创建连接后创建模型,即可解决问题。
修改后的代码示例:
class aMainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
QMainWindow.__init__(self)
# Set up the user interface from Designer.
self.setupUi(self)
#self.db.setDatabaseName('testdb.db')
self.model = QSqlTableModel(self)
self.model.setTable("records")
self.model.setSort(FILEORDER, Qt.AscendingOrder)
self.model.setHeaderData(ID, Qt.Horizontal, QVariant("ID"))
self.model.setHeaderData(FILEORDER, Qt.Horizontal, QVariant("File Order"))
self.model.setHeaderData(RECORDTYPE, Qt.Horizontal, QVariant("Type"))
self.model.setHeaderData(NAME, Qt.Horizontal, QVariant("Name"))
self.model.setHeaderData(PRESORTNAME, Qt.Horizontal, QVariant("Presort Name"))
self.model.setHeaderData(RECORD, Qt.Horizontal, QVariant("Record"))
self.model.select()
self.tableView.setModel(self.model)
#self.view.setSelectionMode(QTableView.SingleSelection)
#self.view.setSelectionBehavior(QTableView.SelectRows)
self.tableView.setColumnHidden(ID, True)
self.tableView.setColumnHidden(PRESORTNAME, True)
self.tableView.setColumnHidden(RECORD, True)
#slot of the open db action
def on_actionOpen_DB_triggered(self, checked=None):
if checked is None: return
filename = QFileDialog.getOpenFileName(self, 'open a database',
'/home/',
"Databases (*.db)", #All Files (*.*)
"Databases (*.db)")
if not filename:
pass
self.db = QSqlDatabase.addDatabase("QSQLITE")
if self.db.isOpen():
sys.stdout.write('db still open?')
self.db.setDatabaseName(filename)
self.dbname = filename
self.db.open()
self.model.select() # 将模型的 select() 方法移到此处
#self.tableView.update()
if self.db.isOpen():
sys.stdout.write('db opened')
通过这种方式,可以在更换数据库后成功填充 QTableView 的数据。