Python,Qt,ComboBox,两列?
Posted
技术标签:
【中文标题】Python,Qt,ComboBox,两列?【英文标题】:Python, Qt, ComboBox, two columns? 【发布时间】:2020-05-12 15:25:42 【问题描述】:问题很简单,但是目前的答案有问题:
我将 QT 与 Python 和 SQL 结合使用。 我得到了一些查询数据:“从部门中选择 ID,部门” 我想创建包含两列(id、department)的组合框,它将只显示“department”(department 1、department 2 .. etc),但选择后,它应该返回“id”。
换句话说:我正在为 c# 中的组合框寻找与 displaymember 和 valuemember 相同的功能。
我设法在 Combobox 中创建了一个 Qtableview,但是一个问题会导致另一个问题(视图、读取“id”等)。 还有其他更简单的方法吗?
【问题讨论】:
你用什么库发出 SQL 请求? 通常我使用 PYODBC 进行 SQL 连接。在这种情况下,我将 QSqlTableModel 用于组合框模型(我记得 - 我现在没有代码在我面前)。 【参考方案1】:正如 OP 指出它使用 QSqlTableModel,那么模仿 C# 行为的可能解决方案是建立将通过 modelColumn 属性显示的列,然后使用与所选行关联的 QSqlRecord。
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,Qt,ComboBox,两列?的主要内容,如果未能解决你的问题,请参考以下文章
QT中ComboBox如何获取选中的文本内容??下面程序出错了,如何改正?