【问题标题】:How to have multiple columns in a QComboBox with a QAbstractTableModel如何使用 QAbstractTableModel 在 QComboBox 中有多个列
【发布时间】:2020-10-25 11:37:52
【问题描述】:

我见过与此类似的问题,但它们针对的是 QTableView。这不是使用那个,这只是用于带有自定义 QAbstractTableModel 的下拉列表(QComboBox),它需要有 2 列。

重大更新
(注意:遗留代码已被删除,因为这是解决同一问题的更好方法,遗留代码令人困惑)。

好的,所以为了赶上@eyllanesc 解释的内容,我将其从 QAbstractListModel 更改为 QAbstractTableModel。结果是:

class ModelForComboboxesWithID(QAbstractTableModel):
    """Create our basic model"""

    def __init__(self, program, records):
        super(ModelForComboboxesWithID, self).__init__()
        self._data = records
        self.program = program
        self.path_images = program.PATH_IMAGES

    def rowCount(self, index: int = 0) -> int:
        """The length of the outer list. Structure: [row, row, row]"""
        if not self._data:
            return 0  # Doubt: Do we need to return this if self._data is empty?
        return len(self._data)

    def columnCount(self, index: int = 0) -> int:
        """The length of the sub-list inside the outer list. Meaning that Columns are inside rows
        Structure: [row [column], row [column], row [column]]"""
        if not self._data:
            return 0  # Doubt: Do we need to return this if self._data is empty?
        return len(self._data[0])

    def data(self, index, role=None):
        """return the data on this index as data[row][column]"""
        # 1 - Display data based on its content (this edits the text that you visually see)
        if role == Qt.DisplayRole:
            value = self._data[index.row()][index.column()]
            return value
        # 2 - Tooltip displayed when hovering on it
        elif role == Qt.ToolTipRole:
            return f"ID: {self._data[index.row()][1]}"

我是这样设置的:

def eventFilter(self, target, event: QEvent):
    if event.type() == QEvent.MouseButtonPress:
        if target == self.Buscadorcombo_cliente:
           records = ... # my query to the database
           set_combo_records_with_ids(self.program, target, records)
           target.currentIndexChanged.connect(self.test)

def set_combo_records_with_ids(program, combobox: QComboBox, records):
    """Clear combobox, set model/data and sort it"""
    combobox.clear()
    model = ModelForComboboxesWithID(program, records)
    combobox.setModel(model)
    combobox.model().sort(0, Qt.AscendingOrder)
    combobox.setModelColumn(0)

这个结果几乎完美:

  • 在下拉菜单(组合框)上显示名称。
  • 如果您将鼠标悬停在某个项目上,它会显示 ID。

现在我可以通过这种方式获取它的任何数据。

def test(self, index):
    data_id = self.Buscadorcombo_cliente.model().index(index, 1).data()
    data_name = self.Buscadorcombo_cliente.model().index(index, 0).data()
    print(data_id)
    print(data_name)

【问题讨论】:

    标签: python pyside2


    【解决方案1】:

    您必须将 QTableView 设置为视图:

    from PySide2 import QtGui, QtWidgets
    
    
    def main():
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = QtWidgets.QWidget()
    
        combo = QtWidgets.QComboBox()
    
        model = QtGui.QStandardItemModel(0, 2)
        for i in range(10):
            items = []
            for j in range(model.columnCount()):
                it = QtGui.QStandardItem(f"it-{i}{j}")
                items.append(it)
            model.appendRow(items)
    
        combo.setModel(model)
    
        view = QtWidgets.QTableView(
            combo, selectionBehavior=QtWidgets.QAbstractItemView.SelectRows
        )
        combo.setView(view)
    
        view.verticalHeader().hide()
        view.horizontalHeader().hide()
    
        header = view.horizontalHeader()
        for i in range(header.count()):
            header.setSectionResizeMode(i, QtWidgets.QHeaderView.Stretch)
    
        lay = QtWidgets.QVBoxLayout(w)
        lay.addWidget(combo)
        lay.addStretch()
        w.resize(640, 480)
        w.show()
    
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 是的,我知道它可以用 QTableView 来完成(实际上在寻找这个时在另一个答案中看到了你的这段代码,很好的复制/粘贴哈哈)但我想知道它是否可以也可以在没有桌子的情况下完成。
    • @Saelyth 为什么?如果您不想连接字符串,那么下一个选项是使用 QTableView
    • @Saelyth 为什么说复制和粘贴很好?您可以将链接指向我,因为如果我找到它,我不会发布答案,您会明白我有很多答案(+5000),所以我很难找到它们
    • 我在这里看到的。第二种解决方案:stackoverflow.com/questions/59927987/… 我现在看到它们并不完全相同,但是您以相同的方式创建 QStandardItems,这让我很困惑,抱歉。
    • 我不想要 QTableView 的原因是因为在一个完美的场景中我只想显示项目的“名称”,但是当点击它时我想获取“ID”其中,而不是名称,有时我想同时使用两者,但是我希望隐藏 ID,除非您将鼠标悬停在其上。 (最后一部分很容易在模型中使用Qt.ToolTipRole)。我发现添加表格有点矫枉过正,但我​​不明白如何在单击表格的某个项目时实现它,它只会采用 ID 或名称,或两者兼而有之(取决于不同的情况)。
    猜你喜欢
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    相关资源
    最近更新 更多