Python,Qt,ComboBox,两列? [英] Python, Qt, ComboBox, two columns?

查看:60
本文介绍了Python,Qt,ComboBox,两列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题很简单,但就答案而言,有一个问题:

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# 中的组合框寻找与 displaymembervaluemember 相同的功能.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆