美文网首页走进Qt程序世界
QSortFilterProxyModel + Qml Lisv

QSortFilterProxyModel + Qml Lisv

作者: BeeTom | 来源:发表于2019-05-29 09:59 被阅读0次

在前端开发中,我们经常要实现分页内容,这里介绍如何通过QSortFilterProxyModel + Qml Listview实现分页。


分页效果图
思路
结构图
  1. QSortFilterProxyModel详细内容可以看Qt文档,这里主要介绍我们继承这个类要实现的部分。我们继承这个类通过实现抽象函数filterAcceptsRow来实现单个页面的内容过滤。
    给qml暴露下面属性
  • pageSize
  • pageIndex
  • count

PageModelSorter.h

#include <QSortFilterProxyModel>

class PageModelSorter: public QSortFilterProxyModel{
    Q_OBJECT
    Q_PROPERTY(int pageIndex READ pageIndex WRITE setPageIndex NOTIFY pageIndexChanged)
    Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged)
    Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
    PageModelSorter(QObject* parent);
    ~PageModelSorter();

    int pageIndex() const;
    void setPageIndex(int pageIndex);

    int pageSize() const;
    void setPageSize(int pageSize);

    int count() const;

signals:
    void pageIndexChanged(const int& pageIndex);
    void pageSizeChanged(const int& pageSize);
    void countChanged(const int& count);

protected:

    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
    bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;

private:
    int m_pageIndex;
    int m_pageSize;
};

PageModelSorter.cpp

#include "modelsorter.h"

PageModelSorter::PageModelSorter(QObject *parent):
    QSortFilterProxyModel (parent)
{
    emit countChanged(rowCount());
}

PageModelSorter::~PageModelSorter()
{
}

bool PageModelSorter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    Q_UNUSED(source_parent);

    int min = m_pageSize * m_pageIndex;
    int max = m_pageSize * m_pageIndex + m_pageSize;
    return source_row >= min && source_row < max;
}

bool PageModelSorter::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    return QSortFilterProxyModel::lessThan(source_left, source_right);
}

int PageModelSorter::pageSize() const
{
    return m_pageSize;
}

void PageModelSorter::setPageSize(int pageSize)
{
    m_pageSize = pageSize;
    emit pageSizeChanged(pageSize);
    emit layoutChanged();
}

int PageModelSorter::count() const
{
    return rowCount();
}

int PageModelSorter::pageIndex() const
{
    return m_pageIndex;
}

void PageModelSorter::setPageIndex(int pageIndex)
{
    m_pageIndex = pageIndex;
    emit pageIndexChanged(pageIndex);
    emit layoutChanged();
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "pagemodel.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlRegisterType<PageModelSorter>("PageModel", 1, 0, "PageModel");

    auto builder = new ModelBuilder<ISong, SongOperate>(&lDatas);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
  1. qml端实现
    PageDelegate.qml
import QtQuick 2.0
import PageModel 1.0

Rectangle{
    property int pageNo;
    property QtObject source;
    property int sizeInPage;
    id: page
    Grid{
        anchors.centerIn: parent
        spacing: 10
        columns: 5
        Repeater{
            model: PageModel{
                sourceModel: source
                pageIndex: pageNo
                pageSize: sizeInPage
            }
            delegate: SongDelegate{}
        }
    }
}

SongDelegate.qml

import QtQuick 2.0

Rectangle{
    width: 200
    height: 100
    border.width: 1
    border.color: "#7799aa"
    color: "#aaeeff"
    radius: 4
    Column{
        anchors.centerIn: parent
        spacing: 10
        Text{
            text: "歌名: " + SongName
        }
        Text{
            text: "歌手: " + SingerName
        }
        Text{
            text: "歌号: " + SongNo
        }
    }
}

SongPage.qml

import QtQuick 2.0
import QtQuick.Controls 2.5
import "./Delegates"


Item {
    property int pageSize: 20
    property int pageCount: songModel.rowCount() % pageSize === 0 ? songModel.rowCount() / pageSize : Math.round(songModel.rowCount() / pageSize) + 1

    Column{
        anchors.fill: parent
        ListView{
            id:listView
            orientation: ListView.Horizontal
            width: parent.width
            height: parent.height - 60
            model: pageCount
            highlightRangeMode : ListView.StrictlyEnforceRange
            highlightMoveDuration: 200
            highlightMoveVelocity: -1
            snapMode: ListView.SnapOneItem
            delegate: PageDelegate{
                pageNo: index
                source: songModel
                sizeInPage: pageSize
                width: listView.width
                height: listView.height
            }
        }

        Item{
            width: parent.width
            height: 60
            Row{
                anchors.centerIn: parent
                spacing: 20

                Button{
                    text: "Previous"
                    width: 70
                    height: 40
                    onClicked: {
                        if(listView.currentIndex > 0)
                            listView.currentIndex -= 1
                    }
                }

                Text{
                    text: String(listView.currentIndex + 1) + "/" + String(pageCount)
                    anchors.verticalCenter: parent.verticalCenter
                }

                Button{
                    text: "Next"
                    width: 70
                    height: 40
                    onClicked: {
                        if(listView.currentIndex < pageCount - 1)
                            listView.currentIndex += 1
                    }
                }
            }
        }
    }

}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 1300
    height: 600
    minimumHeight: 600
    minimumWidth: 1200
    title: qsTr("Hello World")

    SongPage{
        anchors.fill: parent
    }
}

相关文章

网友评论

    本文标题:QSortFilterProxyModel + Qml Lisv

    本文链接:https://www.haomeiwen.com/subject/frtetctx.html