简体   繁体   English

Python,Qt,ComboBox,两列?

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

The question is quite simple, but as far there is a problem with the answer:这个问题很简单,但就答案而言,有一个问题:

I'm using QT with Python and SQL.我在 Python 和 SQL 中使用 QT。 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".我正在获取一些查询数据:“选择 id,来自部门的部门”我想创建带有两列(id、部门)的组合框,它将只显示“部门”(部门 1、部门 2 ......等),但之后选择,它应该返回“id”。

In other words: i'm looking for same functionality as displaymember and valuemember for combobox in c#.换句话说:我正在寻找与 C# 中组合框的displaymembervaluemember相同的功能。

I managed to create a Qtableview in Combobox, but one problem creates another (view, reading "id" etc.).我设法在 Combobox 中创建了一个 Qtableview,但是一个问题又创建了另一个问题(视图、读取“id”等)。 is there any other easier way?还有其他更简单的方法吗?

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.由于 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_())

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.另一种解决方案是,根据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_())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM