如何在 QtQuick 2 中对 QML TableView 进行排序?
我想用 Qt 5.1 实现一个带有自定义角色的可排序 TableView.但是当用户点击标题时,我不知道该怎么做才能使其排序.
I want to implement a sortable TableView with custom roles with Qt 5.1. But I don't know what to do more to make it sorted when user clicked on header.
在我的 Qt .pro 文件中,我添加了:
in my Qt .pro file, I added:
!android: !ios: !blackberry: qtHaveModule(widgets): QT += widgets
在 main.cpp 中,我使用 QtWidgets/QApplication
作为全局应用程序实例,并将 qmlRegisterType 用于我的新模型类(见下文):
in main.cpp, I used QtWidgets/QApplication
as global app instance, and used qmlRegisterType for my new model class(see below):
qmlRegisterType<PositionModel>("MyDataModule", 1, 0, "PositionModel");
PositionModel 声明如下:
PositionModel is declared following:
class PositionModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum PositionRoles {
CustomRol1 = Qt::UserRole + 1,
CustomRow2,
PositionRoleMaxPlus1
};
explicit PositionModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
void setData(QList<QObject*> data);
protected:
QHash<int, QByteArray> roleNames() const;
private:
QList<QObject*> m_data;
signals:
public slots:
};
并实现如下:
PositionModel::PositionModel(QObject *parent) :
QAbstractTableModel(parent)
{
}
QHash<int, QByteArray>
PositionModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[CustomRole1] = "CustomRole1";
roles[CustomRole2] = "CustomRole2";
return roles;
}
int
PositionModel::rowCount(
const QModelIndex &parent) const
{
return m_data.size();
}
int
PositionModel::columnCount(
const QModelIndex &parent) const
{
return 2; // two custom rows
}
QVariant
PositionModel::data(
const QModelIndex &index, int role) const
{
if (!index.isValid() || (role != Qt::DisplayRole && role<Qt::UserRole))
return QVariant();
MyObject* myobj=dynamic_cast<MyObject*>(m_data[index.row()]);
switch(role){
case CustomRole1:
{
return QVariant(myobj->attribute1());
break;
}
case CustomRole2:
{
return QVariant(myobj->attribute2());
break;
}
default:
{
break;
}
}
return QVariant();
}
QVariant
PositionModel::headerData(
int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole && role<Qt::UserRole)
return QVariant();
if (orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return tr("CustomRole1");
case 1:
return tr("CustomRole2");
}
return QVariant();
}
bool
PositionModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
return false;
}
void
PositionModel::setData(QList<QObject*> data)
{
m_data=data;
}
我的 .qml 文件是:
and my .qml file is:
import QtQuick 2.1
import QtQuick.Controls 1.0
import StockModule 2.0
TableView {
id: positionlisttable
sortIndicatorVisible: true
model: mydata.currentPosition // here "mydata" is an instance of MyData class and is set as a context property to QML. "currentPosition" is a Q_PROPERTY in MyData class, and its return type is QAbstractItemData*.
TableViewColumn {
role: "CustomRole1"
title: "CustomRole1"
width: 80
}
TableViewColumn {
role: "CustomRole2"
title: "CustomRole2"
width: 80
}
}
在 MyData 类中:
and in MyData class:
/*QAbstractItemModel*/QObject*
MyData::currentPosition() const
{
PositionModel* newmd=new PositionModel();
newmd->setData(m_d->data());
QSortFilterProxyModel *filterModel = new QSortFilterProxyModel();
filterModel->setSourceModel(newmd);
filterModel->setSortRole(PositionModel::CustomRole1);
filterModel->setDynamicSortFilter(true);
return filterModel;
}
那么现在我应该怎么做才能使其可排序?
so now what should I continue to do to make it sortable?
推荐答案
将以下代码添加到 QML:
Add the following code to the QML:
TableView
{
...
onSortIndicatorColumnChanged: model.sort(sortIndicatorColumn, sortIndicatorOrder)
onSortIndicatorOrderChanged: model.sort(sortIndicatorColumn, sortIndicatorOrder)
}
确保您的 C++ 模型具有可访问的 sort() 方法,例如:
Make sure that your C++ model has the accessible sort() method, for example:
class MySortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
...
Q_INVOKABLE virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
{
qDebug("Sorting by column %d", column);
QSortFilterProxyModel::sort(column, order);
}
}
你可以用不同的方式命名方法,我更喜欢覆盖现有的方法 sort().
You can name the method in a different way, I prefer to override the existing method sort().
相关文章