2014-06-16 6 views
1

QT에서 QAbstractTableModel의 qml 및 setData 함수에 TableView를 연결하는 데 문제가 있습니다. 내 생각은 CkeckBox 대리인을 통해 활동을 "완료"로 확인할 수 있습니다. 나는 행 대신 QmodelIndex를 사용하고 qml-file에서 매개 변수로 view.currentrow를 보내기 위해 setData 함수를 덮어 쓰려고 시도했다. 하지만 작동하지 않습니다 (currentrow는 항상 기본값 -1 값을 보냅니다).QtQuick TableView CheckBox 대리자 QAbstractTableModel의 setData 함수를 호출합니다.

main.qml

import QtQuick 2.0 
import QtQuick.Window 2.1 
import QtQuick.Controls 1.1 
import QtQuick.Dialogs 1.0 
import TodoM 1.0 

Rectangle{ 
width: 600 
height: 400 

TextField{ 
    id:activityDescriptionTextEdit 
    anchors.top: parent.top 
    width: 500 
    height: 50 
} 
Button{ 
    id: saveActivityButton 
    text: "Save Activity" 
    anchors.left: activityDescriptionTextEdit.right 
    onClicked: myModel.appendTodoFromQtQuick (activityDescriptionTextEdit.text) 
} 

TextField{ 
    id: filePathDisplay 
    anchors.top: activityDescriptionTextEdit.bottom 
    width: 500 
    height: 50 
} 
Button{ 
    text: "Save File" 
    anchors.left: filePathDisplay.right 
    anchors.top: activityDescriptionTextEdit.bottom 
    onClicked: saveFileDialog.open() 
} 

TableView{ 
id:view 
    anchors.top: filePathDisplay.bottom 
    width: 500 
    height: 400 

    TableViewColumn{ 
     id: firstColumn 
     title: "Is Done" 
     role: "isDoneStateCheckState" 
     width:100; 
     delegate: CheckBox { 
      id: checkBox 
      onCheckedChanged: { 
       //Here is where I want to call setData 
      } 
     } 
    } 

    TableViewColumn{ 

     title: "Activity" 
     role: "activityDescriptionState" 
     width:200 
    } 

    TableViewColumn{ 
     role: "timeStampState" 
     width:200 
    } 
    model: myModel 
} 
FileDialog{ 
    id: saveFileDialog 
    title: "Save File As" 
    selectExisting: false 
    selectMultiple: false 
    nameFilters: "*txt" 
    onAccepted: { 
     _ft.saveFile(saveFileDialog.fileUrl, myModel) 
    } 

    onRejected: { 
     console.log("Canceled") 
    } 
} 

}

TodoModel.cpp

#include "TodoModel.h" 
    #include "QModelIndex" 
    #include "QDebug" 

    TodoModel::TodoModel(QObject *parent) 
    : QAbstractTableModel(parent) 

    { 

    } 

    TodoModel::~TodoModel() 
    { 
     } 

    QModelIndex TodoModel::parent(const QModelIndex& child) const 
    { 
    Q_UNUSED(child) 

    return QModelIndex(); 
    } 

    int TodoModel::rowCount(const QModelIndex& parent) const 
    { 
    Q_UNUSED(parent) 

    return m_todos.count(); 
    } 

    int TodoModel::columnCount(const QModelIndex& parent) const 
    { 
    Q_UNUSED(parent) 

    return ColumnsCount; 
    } 

    QVariant TodoModel::data(const QModelIndex& index, int role) const 
    { 
    int columnIndex = index.column(); 
    const int rowIndex = index.row(); 
    switch (role) 
    { 
     case IsDoneRole: 
     case IsDoneCheckStateRole: 
      columnIndex = ColumnIndexIsDone; 
      break; 
     case ActivityDesctriptionRole: 
      columnIndex = ColumnIndexActivityDescription; 
      break; 
     case TimeStampRole: 
      columnIndex = ColumnIndexTimestamp; 
      break; 
     default: 
      break; 
    } 
    if (! this->isValidColumnIndex(columnIndex) 
     || ! this->isValidRowIndex(rowIndex)) 
    { 
     return QVariant(); 
    } 
    const Todo& todo = m_todos[ rowIndex ]; 
    switch (columnIndex) 
    { 

     case ColumnIndexIsDone: 
      if (role == Qt::CheckStateRole 
       || role == IsDoneCheckStateRole) 
      { 
       return todo.isDone() 
         ? Qt::Checked 
         : Qt::Unchecked; 
      } 
      else if (role == Qt::UserRole 
         || role == IsDoneRole) 
      { 
       return todo.isDone(); 
      } 

      break; 

     case ColumnIndexActivityDescription: 
      if (role == Qt::DisplayRole) 
      { 

       return todo.activityDescription(); 
      } 
      else if (role == Qt::UserRole 
         || role == ActivityDesctriptionRole) 
      { 

       return todo.activityDescription(); 
      } 
      //Maham Brake-ovete i stava o.O 

      break; 

     case ColumnIndexTimestamp: 
      if (role == Qt::DisplayRole) 
      { 
       return todo.addedTimestamp().toString("dd/MM/yyyy hh:mm:ss.zzz"); 
      } 
      else if (role == Qt::UserRole 
         || role == TimeStampRole) 
      { 
       return todo.addedTimestamp(); 
      } 

      break; 

     default: 
      break; 
    } 

    return QVariant(); 
    } 

    QVariant TodoModel::headerData(int section, Qt::Orientation orientation, int role)  const 
    { 
    if (! this->isValidColumnIndex(section) 
     || orientation != Qt::Horizontal 
     || role != Qt::DisplayRole) 
    { 
     return QVariant(); 
    } 

    switch (section) 
    { 
     case ColumnIndexIsDone: 
      return tr("Is Done"); 
     case ColumnIndexActivityDescription: 
      return tr("Activity Description"); 
     case ColumnIndexTimestamp: 
      return tr("Timestamp"); 
     default: 
      break; 
    } 

    return QVariant(); 
    } 

    Qt::ItemFlags TodoModel::flags(const QModelIndex& index) const 
    { 
    Qt::ItemFlags finalFlags = QAbstractTableModel::flags(index); 
    if (index.column() == ColumnIndexIsDone) 
    { 
     finalFlags |= Qt::ItemIsUserCheckable; 
    } 

    return finalFlags; 
    } 
    bool TodoModel::setData(const QModelIndex& index, const QVariant& value, int role) 
    { 

    const int rowIndex = index.row(); 
    const int columnIndex = index.column(); 
    if (! this->isValidRowIndex(rowIndex) 
     || ! this->isValidColumnIndex(columnIndex)) 
    { 
     return false; 
    } 

    Todo& todo = m_todos[ rowIndex ]; 

    switch (columnIndex) 
    { 
     case ColumnIndexIsDone: 
     { 
      if (role != Qt::CheckStateRole 
       && role != IsDoneRole 
       && role != IsDoneCheckStateRole) 
      { 
       return false; 
      } 

      bool converted = false; 
      const Qt::CheckState checkState = static_cast<Qt::CheckState> (value.toInt(& converted)); 
      const bool isChecked = checkState == Qt::Checked; 
      if (! isChecked 
       && checkState != Qt::Unchecked) 
      { 
       return false; 
      } 

      if (todo.isDone() == isChecked) 
      { 
       return false; 
      } 

      todo.setIsDone(isChecked); 
      QModelIndex index; 
      index = index.child(rowIndex, 0); 
      emit dataChanged(index, index); 

      break; 
     } 
     default: 
      break; 
    } 

    return true; 
    } 

    void TodoModel::appendTodo(const Todo& aTodo) 
    { 
    const int previousRowsCount = this->rowCount(); 
    this->beginInsertRows(QModelIndex(), previousRowsCount, previousRowsCount); 
    m_todos.append(aTodo); 

    this->endInsertRows(); 
} 

    void TodoModel::clear() 
    { 
    const int rowsCount = this->rowCount(); 
    if (rowsCount <= 0) 
    { 
     return; 
    } 

    this->beginRemoveRows(QModelIndex(), 0, rowsCount - 1); 
    m_todos.clear(); 
    this->endRemoveRows(); 
    } 

    bool TodoModel::isValidColumnIndex(const int columnIndex) const 
    { 
    return 0 <= columnIndex && columnIndex < this->columnCount(); 
    } 

     bool TodoModel::isValidRowIndex(const int rowIndex) const 
     { 
     return 0 <= rowIndex && rowIndex < this->rowCount(); 
     } 
     QList<Todo> TodoModel::todos() const 
     { 
     return m_todos; 
     } 


     void TodoModel::appendTodoFromQtQuick(QString aActivityDescription) 
     { 
     Todo todo; 
     todo.setIsDone(false); 
     todo.setActivityDescription(aActivityDescription); 
     todo.setAddedTimestamp(QDateTime::currentDateTime()); 
     appendTodo(todo); 
     } 

     QHash<int, QByteArray> TodoModel::roleNames() const 
     { 
     QHash<int, QByteArray> roles; 
     roles[IsDoneRole] = "isDoneState"; 
     roles[IsDoneCheckStateRole] = "isDoneStateCheckState"; 
     roles[ActivityDesctriptionRole] = "activityDescriptionState"; 
     roles[TimeStampRole] = "timeStampState"; 
     return roles; 
     } 

TodoModel.h

#ifndef TODOMODEL_H 
#define TODOMODEL_H 

#include "Todo.h" 

#include <QAbstractTableModel> 
#include <QList> 

enum ColumnIndex 
{ 
    ColumnIndexIsDone    = 0, 
    ColumnIndexActivityDescription = 1, 
    ColumnIndexTimestamp   = 2, 
    ColumnsCount     = 3 
}; 



class TodoModel : public QAbstractTableModel 
{ 
    Q_OBJECT 

public: 
    explicit TodoModel(QObject* parent = 0); 
    virtual ~TodoModel(); 

    enum TodoColumnRoles { 
     IsDoneRole    = Qt::UserRole + 1, 
     IsDoneCheckStateRole  = Qt::UserRole + 2, 
     ActivityDesctriptionRole = Qt::UserRole + 3, 
     TimeStampRole   = Qt::UserRole + 4 
    }; 

    virtual QModelIndex parent(const QModelIndex& child) const; 
    virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; 
    virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; 
    virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; 
    virtual QVariant headerData(int section, Qt::Orientation orientation, 
           int role = Qt::DisplayRole) const; 
    // https://[email protected]/Radost/qtquickcontrols.git 
    Qt::ItemFlags flags(const QModelIndex& index) const; 
    Q_INVOKABLE virtual bool setData(const QModelIndex& index, const QVariant &value, int role = Qt::EditRole); 

    void appendTodo(const Todo& aTodo); 
    void clear(); 

    bool isValidColumnIndex(const int columnIndex) const; 
    bool isValidRowIndex(const int rowIndex) const; 

    Q_INVOKABLE QList<Todo> todos() const; 
    //Q_INVOKABLE QList<Todo*> ptodos() const; 

public slots: 

    Q_INVOKABLE void appendTodoFromQtQuick(QString aActivityDescription); 
protected: 
    QHash<int, QByteArray> roleNames() const; 
private: 
    QList<Todo> m_todos; 
    //Q_QList< Todo* > m_ptodos; 

}; 

#endif // TODOMODEL_H 

나는이 작업을 수행 할 수있는 방법 어떤 생각?

답변

0

코드는 읽고 유지해야하는 악몽입니다. 당신의 탭과 공백을 처리하십시오. 당신은 위임에 (역할 이름처럼 불리는) 변수를 설정하여 암시 적으로 setData 전화

:

enum TodoColumnRoles { 
    IsDoneRole = Qt::UserRole, 
    IsDoneCheckStateRole, 
    ActivityDesctriptionRole, 
    TimeStampRole 
}; 

는 하나가 있어야합니다 : 열거 형은 자동으로 열거

TableViewColumn{ 
    id: firstColumn 
    title: "Is Done" 
    role: "isDoneStateCheckState" 
    width:100; 
    delegate: CheckBox { 
     id: checkBox 
     onCheckedChanged: { 
      isDoneState = checked 
     } 
    } 
} 

, 갈 큰 스위치 문 setDatarole 다른 값을 찾습니다.

그것은 dataChanged()에 대한 새 인덱스를 생성 할 말이 없습니다 : 그것은 유일하게 가능한 정확한 값을 가지고 있기 때문에

QModelIndex index; 
index = index.child(rowIndex, 0); 
emit dataChanged(index, index); 

당신은 setData(const QModelIndex& index ...의 매개 변수를 재사용해야한다.