我无法连接 qml 中的 TableView 和 QT 中 QAbstractTableModel 的 setData 函数。我的想法是能够通过 CkeckBox 委托将活动检查为“已完成”。我尝试覆盖 setData 函数以使用 row 而不是 QmodelIndex 并将其 view.currentrow 作为参数从 qml 文件发送。但它不起作用(currentrow 总是发送默认的 -1 值)。
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://Radost@bitbucket.org/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
知道我该怎么做吗?