使用排序的 QAbstractTableModel 时,如何将“Select item ...”添加到 QComboBox?
How to add “Select item…” to QComboBox when using sorted QAbstractTableModel?
我希望将排序的 QAbstractListModel
设置为 QComboBox
并始终将 "Select item..." 显示为组合框中的第一个值。
每当我使用排序时,"Select item..." 项目会与所有其他项目一起意外排序:
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_()
由于模型不知道代理,我怎样才能可靠地插入 "Select item..." 以始终显示为组合框中的第一项?
这应该可以满足您的要求...
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
我希望将排序的 QAbstractListModel
设置为 QComboBox
并始终将 "Select item..." 显示为组合框中的第一个值。
每当我使用排序时,"Select item..." 项目会与所有其他项目一起意外排序:
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_()
由于模型不知道代理,我怎样才能可靠地插入 "Select item..." 以始终显示为组合框中的第一项?
这应该可以满足您的要求...
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