使用排序的 QAbstractTableModel 时如何将“选择项目...”添加到 QComboBox?

Posted

技术标签:

【中文标题】使用排序的 QAbstractTableModel 时如何将“选择项目...”添加到 QComboBox?【英文标题】:How to add “Select item…” to QComboBox when using sorted QAbstractTableModel? 【发布时间】:2018-06-25 14:20:52 【问题描述】:

我希望将已排序的 QAbstractListModel 设置为 QComboBox 并始终将“选择项目...”显示为组合框中的第一个值。

每当我使用排序时,“选择项目...”项目都会与所有其他项目一起排序:

import sys

from PySide2 import QtCore  # or PyQt5
from PySide2 import QtWidgets  # or PyQt5

import natsort  # pip install natsort


class NatSort(QtCore.QSortFilterProxyModel):

    def __init__(self, parent=None):
        super(NatSort, self).__init__(parent)

    def lessThan(self, left, right):
        left_data = self.sourceModel().data(left, role=QtCore.Qt.DisplayRole)
        right_data = self.sourceModel().data(right, role=QtCore.Qt.DisplayRole)

        sorted_data = natsort.natsorted([left_data, right_data])

        if left_data == sorted_data[0]:
            return True
        return False


class ListModel(QtCore.QAbstractListModel):

    def __init__(self, items=[], parent=None):
        QtCore.QAbstractListModel.__init__(self, parent)
        self._items = items

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self._items) + 1  # adjust row count

    def data(self, index, role):

        row = index.row() - 1  # adjust row count

        if role == QtCore.Qt.DisplayRole:
            if row >= 0:
                obj = self._items[row]
                return obj
            else:
                return 'Select item...'


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    button = QtWidgets.QComboBox()

    data = ['m', '?', 'A', 'X', '1', 'b']

    model = ListModel(items=data)
    proxy_model = NatSort()
    # proxy_model = QtCore.QSortFilterProxyModel()  # same results
    proxy_model.setSourceModel(model)
    proxy_model.sort(0, QtCore.Qt.AscendingOrder)
    button.setModel(proxy_model)

    button.show()
    app.exec_()

由于模型不知道代理,我怎样才能可靠地插入“选择项...”以始终显示为组合框中的第一项?

【问题讨论】:

您还没有完全发布足够的代码来使其成为可运行的示例。将其刷新,以便它使用一些示例数据运行,这样我们就可以看到您所看到的行为。 我添加了一个完整的示例以及一个屏幕截图。 【参考方案1】:

这应该做你想要的......

class NatSort(QtCore.QSortFilterProxyModel):
    SPECIAL_ITEM = 'Select item...'

    def lessThan(self, left, right):
        """Custom natural sorting"""
        left_data = self.sourceModel().data(left, role=QtCore.Qt.DisplayRole)
        right_data = self.sourceModel().data(right, role=QtCore.Qt.DisplayRole)

        sorted_data = natsort.natsorted([left_data, right_data])

        if left_data == NatSort.SPECIAL_ITEM:
            return True
        if right_data == NatSort.SPECIAL_ITEM:
            return False
        if left_data == sorted_data[0]:
            return True
        return False

【讨论】:

将此逻辑放入排序算法是有意义的。谢谢!

以上是关于使用排序的 QAbstractTableModel 时如何将“选择项目...”添加到 QComboBox?的主要内容,如果未能解决你的问题,请参考以下文章

将 QAbstractTableModel 实现与自定义类的 QList 一起使用

如何在 QTableView/QAbstractTableModel 中使用多行文本/换行符?

tableview中的QML排序非常缓慢

如何使用 beginMoveRows 在 QTableView (QAbstractTableModel) 中移动一行?

带有使用 QAbstractTableModel 子类的 Qt 小部件的 MVC

使用 beginMoveColumns 在 QTableView (QAbstractTableModel) 中的列没有正确移动?