2014-01-07 76 views
4

我想用Qt 5.1實現一個可自定義角色的可排序TableView。但我不知道該怎麼做才能讓用戶點擊標題時進行排序。如何在QtQuick 2中對QML TableView進行排序?

在我的Qt pro文件,我說:

!android: !ios: !blackberry: qtHaveModule(widgets): QT += widgets 
在main.cpp中

,我用QtWidgets/QApplication作爲全球應用實例,使用qmlRegisterType我的新模型類(見下文):

qmlRegisterType<PositionModel>("MyDataModule", 1, 0, "PositionModel"); 

PositionModel聲明如下:

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文件是:

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的類:

/*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; 
} 

所以現在我應該繼續做,使之可排序?

回答

11

下面的代碼添加到QML:

TableView 
{ 
... 
    onSortIndicatorColumnChanged: model.sort(sortIndicatorColumn, sortIndicatorOrder) 
    onSortIndicatorOrderChanged: model.sort(sortIndicatorColumn, sortIndicatorOrder) 
} 

確保你的C++模型的訪問sort()方法,例如:

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()。

相關問題