Python, Qt, ComboBox, 两列?

Python, Qt, ComboBox, two columns?

问题很简单,但目前答案有问题:

我将 QT 与 Python 和 SQL 一起使用。 我正在获取一些查询数据:'select id, department from departments' 我想创建包含两列(id、部门)的组合框,它将仅显示 "department"(部门 1、部门 2 .. 等),但选择后,它应该 return "id" .

换句话说:我正在为 c# 中的组合框寻找与 displaymembervaluemember 相同的功能。

我设法在 Combobox 中创建了一个 Qtableview,但一个问题会导致另一个问题(查看、阅读 "id" 等)。 还有其他更简单的方法吗?

由于 OP 指出它使用 QSqlTableModel,因此模仿 C# 行为的一种可能解决方案是通过 modelColumn 属性 建立将显示的列,然后访问相应的项目(id和其他字段)使用与所选行关联的 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_())