Python,Qt,ComboBox,两列? [英] Python, Qt, ComboBox, two columns?
问题描述
问题很简单,但就答案而言,有一个问题:
The question is quite simple, but as far there is a problem with the answer:
我将 QT 与 Python 和 SQL 结合使用.我正在获取一些查询数据:选择 id,来自部门的部门"我想创建具有两列(id,部门)的组合框,它只会显示部门"(部门 1,部门 2 .. 等),但选择后,它应该返回id".
I'm using QT with Python and SQL. I'm getting some query data: 'select id, department from departments' I want to create combobox with two columns (id, department), which will display only "department" (department 1, department 2 .. etc), but after selecting, it should return "id".
换句话说:我正在为 c# 中的组合框寻找与 displaymember 和 valuemember 相同的功能.
In other words: i'm looking for same functionality as displaymember and valuemember for combobox in c#.
我设法在 Combobox 中创建了一个 Qtableview,但是一个问题产生了另一个问题(视图、读取id"等).还有其他更简单的方法吗?
I managed to create a Qtableview in Combobox, but one problem creates another (view, reading "id" etc.). is there any other easier way?
推荐答案
正如 OP 指出它使用 QSqlTableModel,那么模仿 C# 行为的可能解决方案是建立将通过 modelColumn 属性显示的列,然后使用与所选行关联的 QSqlRecord 访问相应的项(id 和其他字段).
As the OP notes that it uses QSqlTableModel, then a possible solution to mimic the behavior of C# is to establish the column that will be displayed through the modelColumn property, and then access the corresponding items (id and other fields) using the QSqlRecord associated with the selected row.
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(或其他模型),其中隐藏字段与可以获取的角色相关联.
Another solution is that based on the data obtained by pyodbc you can build a QStandardItemModel (or another model) where the hidden field is associated with a role that can then be obtained.
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,Qt,ComboBox,两列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!