功能
主要用于添加一个可过滤的tableview
分析代码
1 分析main.qml
import QtQuick 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
import org.qtproject.example 1.0
ApplicationWindow {
id: window
visible: true
title: "Table View Example"
toolBar: ToolBar { // 查找框放在工具栏上
TextField {
id: searchBox
placeholderText: "Search..." // 默认文字
inputMethodHints: Qt.ImhNoPredictiveText
width: window.width / 5 * 2
anchors.right: parent.right // 居右
anchors.verticalCenter: parent.verticalCenter
}
}
TableView {
id: tableView
frameVisible: false
sortIndicatorVisible: true
anchors.fill: parent
Layout.minimumWidth: 400
Layout.minimumHeight: 240
Layout.preferredWidth: 600
Layout.preferredHeight: 400
TableViewColumn { // tabview添加列
id: titleColumn
title: "Title"
role: "title" // 这里用到了role,后面配合listmodel
movable: false
resizable: false
width: tableView.viewport.width - authorColumn.width
}
TableViewColumn {
id: authorColumn
title: "Author"
role: "author"
movable: false
resizable: false
width: tableView.viewport.width / 3
}
model: SortFilterProxyModel {
id: proxyModel
source: sourceModel.count > 0 ? sourceModel : null
sortOrder: tableView.sortIndicatorOrder
sortCaseSensitivity: Qt.CaseInsensitive
sortRole: sourceModel.count > 0 ? tableView.getColumn(tableView.sortIndicatorColumn).role : ""
filterString: "*" + searchBox.text + "*"
filterSyntax: SortFilterProxyModel.Wildcard
filterCaseSensitivity: Qt.CaseInsensitive
}
ListModel { // 源model
id: sourceModel
ListElement {
title: "Moby-Dick"
author: "Herman Melville"
}
ListElement {
title: "The Adventures of Tom Sawyer"
author: "Mark Twain"
}
......
}
}
}
2 分析sortfilterproxymodel
看.h
class SortFilterProxyModel : public QSortFilterProxyModel, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(int count READ count NOTIFY countChanged) // count发生变化将触发countChanged信号,并未发现该信号被使用
Q_PROPERTY(QObject *source READ source WRITE setSource)
Q_PROPERTY(QByteArray sortRole READ sortRole WRITE setSortRole)
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder)
Q_PROPERTY(QByteArray filterRole READ filterRole WRITE setFilterRole)
Q_PROPERTY(QString filterString READ filterString WRITE setFilterString)
Q_PROPERTY(FilterSyntax filterSyntax READ filterSyntax WRITE setFilterSyntax)
Q_ENUMS(FilterSyntax)
public:
explicit SortFilterProxyModel(QObject *parent = 0);
QObject *source() const;
void setSource(QObject *source);
QByteArray sortRole() const;
void setSortRole(const QByteArray &role);
void setSortOrder(Qt::SortOrder order);
QByteArray filterRole() const;
void setFilterRole(const QByteArray &role);
QString filterString() const;
void setFilterString(const QString &filter);
enum FilterSyntax {
RegExp,
Wildcard,
FixedString
};
FilterSyntax filterSyntax() const;
void setFilterSyntax(FilterSyntax syntax);
int count() const;
Q_INVOKABLE QJSValue get(int index) const; // 该函数在示例中并未使用过,注释后不影响使用
void classBegin();
void componentComplete();
signals:
void countChanged();
protected:
int roleKey(const QByteArray &role) const;
QHash<int, QByteArray> roleNames() const;
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
private:
bool m_complete;
QByteArray m_sortRole;
QByteArray m_filterRole;
};
sortRole: sourceModel.count > 0 ? tableView.getColumn(tableView.sortIndicatorColumn).role : “”
设置排序的行,sortIndicatorColumn指定的行
再看通过调试可知:示例中是通过modelindex的role将一个listmodel扩展为了一个tablemodel,并且排序的时候对role进行排序,filterAcceptsRow用于显示当前可见的行,通过sortRole进行排序,也可以通过 lessThan()实现
int SortFilterProxyModel::roleKey(const QByteArray &role) const
{
QHash<int, QByteArray> roles = roleNames(); // 本来认为可能会返回非display role等
QHashIterator<int, QByteArray> it(roles);
while (it.hasNext()) {
it.next();
if (it.value() == role)
return it.key();
}
return -1;
}
void SortFilterProxyModel::setSortRole(const QByteArray &role)
{
if (m_sortRole != role) {
m_sortRole = role;
if (m_complete)
QSortFilterProxyModel::setSortRole(roleKey(role));
}
}
QVariant QAbstractItemModel::data(const QModelIndex & index, int role = Qt::DisplayRole) const