PyQt从SQLite数据库填充ComboBox失败及报错问题求助
问题分析与解决方法
错误点梳理
- QSqlTableModel未正确初始化数据库连接:PyQt的
QSqlTableModel依赖QSqlDatabase建立的连接,直接创建模型不会自动关联你的SQLite数据库。 - ComboBox同时使用模型与手动添加项冲突:设置
setModel后,不能再用addItems,两者互斥。 - 方法调用错误:
addItems(self.comboBox_val)是传递方法对象而非执行结果,需改为addItems(self.comboBox_val())。 - 信号绑定逻辑错误:第一段代码中
currentIndexChanged是选中变化时触发,初始加载不会执行comboBox_val,导致ComboBox初始无数据。
方案一:使用QSqlTableModel(推荐)
这是PyQt官方推荐的数据库绑定方式,更符合MVC架构,无需手动处理数据查询与更新:
import sys from PyQt6 import QtWidgets from PyQt6.QtSql import QSqlDatabase, QSqlTableModel from test_rt_sql import Ui_MainWindow class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # 初始化数据库连接 db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName('C:/sqlite/test.db') if not db.open(): print("数据库连接失败:", db.lastError().text()) return # 配置QSqlTableModel self.model = QSqlTableModel(self, db) self.model.setTable('user') self.model.setEditStrategy(QSqlTableModel.EditStrategy.OnManualSubmit) self.model.select() # 设置ComboBox显示的列(指定显示name字段) self.ui.comboBox.setModel(self.model) self.ui.comboBox.setModelColumn(self.model.fieldIndex('name')) self.show() if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
关键说明:
- 必须先通过
QSqlDatabase.addDatabase注册并打开数据库,QSqlTableModel才能正常工作。 setModelColumn用于指定ComboBox显示数据库中的哪一列,这里对应user表的name字段。
方案二:使用sqlite3手动填充ComboBox
如果不想用QtSql模块,可直接用sqlite3查询数据后手动添加项,注意不要设置setModel:
import sys from PyQt6 import QtWidgets import sqlite3 from test_rt_sql import Ui_MainWindow class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # 初始化时填充ComboBox self.fill_comboBox() self.show() def fill_comboBox(self): conn = sqlite3.connect('C:/sqlite/test.db') c = conn.cursor() c.execute('SELECT name FROM user') rows = c.fetchall() # 遍历查询结果,提取name字段添加到ComboBox for row in rows: self.ui.comboBox.addItem(row[0]) # row是元组,取第一个元素即name值 conn.close() if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
关键修正:
- 去掉
setModel调用,避免与手动添加项冲突。 row是sqlite3返回的元组,直接取row[0]获取name字符串,不要用str(row)(会变成类似('张三',)的格式)。- 在
__init__中直接调用fill_comboBox,确保初始加载就填充数据,无需依赖信号触发。
内容的提问来源于stack exchange,提问作者LivsiMD
相关产品推荐
相关产品推荐

