python - Python,Qt,ComboBox,两列?
问题描述
这个问题很简单,但就答案而言,有一个问题:
我将 QT 与 Python 和 SQL 一起使用。我得到一些查询数据:'select id,department from countries' 我想创建带有两列(id,department)的组合框,它将只显示“department”(department 1,department 2 .. etc),但之后选择,它应该返回“id”。
换句话说:我正在寻找与c# 中组合框的displaymember和valuemember相同的功能。
我设法在 Combobox 中创建了一个 Qtableview,但是一个问题产生了另一个问题(视图、读取“id”等)。还有其他更简单的方法吗?
解决方案
正如 OP 指出它使用 QSqlTableModel,那么模仿 C# 行为的可能解决方案是建立将通过 modelColumn 属性显示的列,然后使用与关联的 QSqlRecord 访问相应的项目(id 和其他字段)选定的行。
from PyQt5 import QtCore, QtWidgets, QtSql
def createConnection():
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(":memory:")
if not db.open():
QtWidgets.QMessageBox.critical(
None,
QtWidgets.qApp.tr("Cannot open database"),
QtWidgets.qApp.tr(
"Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information "
"how to build it.\n\n"
"Click Cancel to exit."
),
QtWidgets.QMessageBox.Cancel,
)
return False
query = QtSql.QSqlQuery()
query.exec_(
"CREATE TABLE Departments (id INTEGER PRIMARY KEY AUTOINCREMENT, department TEXT);"
)
query.exec_("INSERT INTO Departments(department) VALUES('department1')")
query.exec_("INSERT INTO Departments(department) VALUES('department2')")
query.exec_("INSERT INTO Departments(department) VALUES('department3')")
query.exec_("INSERT INTO Departments(department) VALUES('department4')")
query.exec_("INSERT INTO Departments(department) VALUES('department5')")
return True
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.model = QtSql.QSqlTableModel(self)
self.model.setTable("Departments")
self.model.select()
self.tableview = QtWidgets.QTableView()
self.tableview.setModel(self.model)
self.combo = QtWidgets.QComboBox()
self.combo.setModel(self.model)
column = self.model.record().indexOf("department")
self.combo.setModelColumn(column)
self.combo.currentIndexChanged.connect(self.onCurrentIndexChanged)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.tableview)
lay.addWidget(self.combo)
@QtCore.pyqtSlot(int)
def onCurrentIndexChanged(self, index):
column = self.model.record().indexOf("id")
r = self.model.record(index)
value = r.value(column)
print(value)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
if not createConnection():
sys.exit(1)
w = Widget()
w.show()
sys.exit(app.exec_())
另一种解决方案是,基于 pyodbc 获得的数据,您可以构建一个 QStandardItemModel(或其他模型),其中隐藏字段与随后可以获得的角色相关联。
from PyQt5 import QtCore, QtGui, QtWidgets
IdRole = QtCore.Qt.UserRole + 1000
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
d = (
(1, "department1"),
(2, "department2"),
(3, "department3"),
(4, "department4"),
(5, "department5"),
)
self.model = QtGui.QStandardItemModel(self)
for id_, value in d:
it = QtGui.QStandardItem(value)
it.setData(id_, IdRole)
self.model.appendRow(it)
self.combo = QtWidgets.QComboBox()
self.combo.setModel(self.model)
self.combo.currentIndexChanged.connect(self.onCurrentIndexChanged)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.combo)
@QtCore.pyqtSlot(int)
def onCurrentIndexChanged(self, index):
id_ = self.combo.itemData(index, IdRole)
# or
# id_ = self.model.item(index).data(IdRole)
print(id_)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
推荐阅读
- python - 重置 Python/Matplotlib 中绘图的默认字体/颜色
- python - sum 每次都可以被列表的一个元素整除
- c - C - 将错误的指针类型传递给函数
- c++ - 我不能在 C++ 上使用 fmt 库头文件
- java - 更新集合内的列表 dbref
- python - 如何在 Python 中使用 BeautifulSoup 从 html 中提取特定文本?
- sql - ORA-00906: 缺少左括号 oracle 错误可能是因为我弄乱了语法
- python - 在python中实现Backwards Euler方法来解决钟摆
- html - 如何仅对 CSS 中的给定形状应用过滤器?
- javascript - 客户端 JS/Angular 中是否存在 HTTP 连接超时?