我有一个ListModel,里面有一些ListElemts。我希望这些元素在ListView中的部分上排序。当我运行时:
Page {
ListModel {
id: listModel
ListElement {
title: "life"
section: "a"
}
ListElement {
title: "universe"
section: "b"
}
ListElement {
title: "and everything"
section: "a"
}
}
ListView {
model: listModel
section {
property: 'section'
delegate: SectionHeader {
text: section
}
}
delegate: ListItem {
Label {
text: model.title
}
}
}
}
它提供了类似的内容:
a
life
b
universe
a
and everything
但是我希望它返回类似的内容:
a
life
and everything
b
universe
我可以通过按上述顺序在模型中排列ListElements来手动实现这一点,但由于ListElements是动态的,因此这并不完美。 如何确保ListElements按照我想要的方式自动排序?
答案 0 :(得分:1)
您可以定义一个函数sortModel
并在Component.onCompleted
ListModel {
id: listModel
ListElement {
title: "life"
section: "a"
}
ListElement {
title: "universe"
section: "b"
}
ListElement {
title: "and everything"
section: "a"
}
function sortModel()
{
for(var i=0; i<count; i++)
{
for(var j=0; j<i; j++)
{
if(get(i).section == get(j).section)
move(i,j,1)
break
}
}
}
Component.onCompleted: sortModel()
}
答案 1 :(得分:0)
对于使用部分,您必须创建Qstandart项模型并设置sortRole(section)并将项附加到qstandard项,并将项附加到模型。之后,您必须设置model-> sort(column)函数对模型进行排序。
查看以下代码:
和c ++代码将是: 你有这样的模型课
#include <QStandardItemModel>
enum TypeContact
{
TitleRole = Qt::UserRole + 1,
SectionRole = Qt::UserRole + 2,
};
class MyModel : public QStandardItemModel
{
Q_OBJECT
public:
MyModel(QObject *parent = 0)
: QStandardItemModel(parent)
{
}
protected:
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> m_roles;
m_roles[TitleRole] = "titleRole";
m_roles[SectionRole] = "sectionRole";
return m_roles;
}
};
以及在另一个类中以及要在其中添加数据以进行模型编写的位置:
//in .h file
QStandardItemModel *model {nullptr};
//.in .cpp file
model = new MyModel(this);
model->clear();
model->setSortRole(sectionRole);
然后插入您的数据。
QStandardItem *item = new QStandardItem;
item->setData( "life", titleRole);
item->setData( "a", sectioRole);
model->appedRow(item);
QStandardItem *item2 = new QStandardItem;
item2->setData( "universal", titleRole);
item2->setData( "b", sectioRole);
model->appedRow(item2);
QStandardItem *item3 = new QStandardItem;
item3->setData( "and every think", titleRole);
item3->setData( "a", sectioRole);
model->appedRow(item3);
并像这样排序模型:
model->sort(0);
qml代码将为:
ListView {
anchors.fill: parent
model: MyModel
delegate: Label {
text: titleRole
width: 100
height: 50
}
section.property: "sectionRole"
section.criteria: ViewSection.FullString
section.delegate: Label {
text: section
font.bold: true
font.pixelSize: 25
}
}
我没有完全测试它,但是它必须可以工作。如果您搜索有关Qstandard项目模型以及如何将其附加到模型并将其设置为模型的信息,则您完全知道必须执行的操作。但是这里setSortRole()和sort()的重要性是。
谢谢
答案 2 :(得分:0)
在这个答案中,我使用Array.protoype.sort()对列表模型进行排序。
var indexes = new Array(listModel.count);
for (var i = 0; i < listModel.count; i++) indexes[i] = i;
console.log(JSON.stringify(indexes)); // [0,1,2]
indexes.sort(function (a, b) { return compareFunc(listModel.get(a), listModel.get(b)); } );
console.log(JSON.stringify(indexes)); // [0,2,1]
var sorted = 0;
while (sorted < indexes.length && sorted === indexes[sorted]) sorted++;
console.log(sorted); // 1
if (sorted === indexes.length) return;
for (i = sorted; i < indexes.length; i++) {
var index = indexes[i];
listModel.move(index, listModel.count - 1, 1);
listModel.insert(index, { } );
}
listModel.remove(sorted, indexes.length - sorted);
以上算法的工作原理:
Array.protoype.sort()
和经过修改的compare函数对数组重新排序以下是OP数据集的有效答案:
Page {
width: 800
height: 480
ListModel {
id: listModel
ListElement {
title: "life"
section: "a"
}
ListElement {
title: "universe"
section: "b"
}
ListElement {
title: "and everything"
section: "a"
}
}
ListView {
id: listView
anchors.fill: parent
model: listModel
section {
property: 'section'
delegate: ItemDelegate {
text: section
font.pointSize: 12
}
}
delegate: ItemDelegate {
text: model.title
font.pointSize: 10
}
}
function listModelSort(listModel, compareFunc) {
var indexes = new Array(listModel.count);
for (var i = 0; i < listModel.count; i++) indexes[i] = i;
console.log(JSON.stringify(indexes)); // [0,1,2]
indexes.sort(function (a, b) { return compareFunc(listModel.get(a), listModel.get(b)); } );
console.log(JSON.stringify(indexes)); // [0,2,1]
var sorted = 0;
while (sorted < indexes.length && sorted === indexes[sorted]) sorted++;
console.log(sorted); // 1
if (sorted === indexes.length) return;
for (i = sorted; i < indexes.length; i++) {
var index = indexes[i];
listModel.move(index, listModel.count - 1, 1);
listModel.insert(index, { } );
}
listModel.remove(sorted, indexes.length - sorted);
}
function compareElements(elem1, elem2) {
return elem1.section.localeCompare(elem2.section);
}
Component.onCompleted: listModelSort(listModel, compareElements)
}