1
我無法連接QT中的TableView和QT中QAbstractTableModel的setData函數。我的想法是能夠通過CkeckBox委託檢查活動「完成」。我嘗試覆蓋setData函數來處理QmodelIndex行,並將其作爲參數從qml文件發送到view.currentrow。但它不起作用(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
任何想法,我該怎麼辦呢?