首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过QIdentityProxyModel向QSqlTableModel添加数据失败

通过QIdentityProxyModel向QSqlTableModel添加数据失败
EN

Stack Overflow用户
提问于 2020-10-25 18:34:59
回答 1查看 48关注 0票数 1

我有一个基于QSqlTableModel的模型:

代码语言:javascript
复制
class QuestionSqlTableModel : public QSqlTableModel
{
    Q_OBJECT
public:
    explicit QuestionSqlTableModel(QObject *parent = nullptr,
                                   const QSqlDatabase &db = QSqlDatabase());

};
代码语言:javascript
复制
QuestionSqlTableModel::QuestionSqlTableModel(
    QObject *parent, const QSqlDatabase &db)
    : QSqlTableModel{parent, db}
{
    setEditStrategy(EditStrategy::OnFieldChange);
}

现在,为了将列映射到qml中使用的角色,我将这个模型安装到一个从QIdentityProxyModel派生的模型中。

一切似乎都很正常。我可以从现有的数据库中读取数据,并通过QIdentityProxyModel将其显示在qml中。

现在,我想从QML中添加一个包含数据的新行。为此,我在QIdentityProxyModel的子级中添加了一个方法。

此模型的完整代码如下:

代码语言:javascript
复制
#include <QObject>
#include <QIdentityProxyModel>

class QuestionsProxyModel : public QIdentityProxyModel
{
    Q_OBJECT

    enum questionRoles {
        idRole = Qt::UserRole + 1,
        askedQuestionRole,
        answer1Role,
        answer2Role,
        answer3Role,
        answer4Role,
        correctAnswerRole,
        pictureRole
    };

public:
    QuestionsProxyModel(QObject* parent = nullptr);

    QHash<int, QByteArray> roleNames() const override;

    Q_INVOKABLE QVariant data(const QModelIndex &index, int role) const override;

    Q_INVOKABLE bool addNewEntry(const QString& askedQuestion,
        const QString& answer1,
        const QString& answer2,
        const QString& answer3,
        const QString& answer4,
        int correctAnswer,
        const QString& picturePath);
private:
    QModelIndex mapIndex(const QModelIndex &index, int role) const;
};
代码语言:javascript
复制
#include <QDebug>
#include <QPixmap>
#include <QBuffer>

#include <QByteArray>

namespace QuestionColumn
{
    static constexpr auto id = 0;
    static constexpr auto askedQuestion = 1;
    static constexpr auto answer1 = 2;
    static constexpr auto answer2 = 3;
    static constexpr auto answer3 = 4;
    static constexpr auto answer4 = 5;
    static constexpr auto correct_answer = 6;
    static constexpr auto picture = 7;
}


QuestionsProxyModel::QuestionsProxyModel(QObject* parent)
    :QIdentityProxyModel(parent)
{
}

QHash<int, QByteArray> QuestionsProxyModel::roleNames() const
{
    QHash <int,QByteArray> roles;
    roles[idRole] = "id";
    roles[askedQuestionRole] = "askedQuestion";
    roles[answer1Role] = "answer1";
    roles[answer2Role] = "answer2";
    roles[answer3Role] = "answer3";
    roles[answer4Role] = "answer4";
    roles[correctAnswerRole] = "correctAnswer";
    roles[pictureRole] = "picture";

    return roles;
}

QVariant QuestionsProxyModel::data(const QModelIndex &index, int role) const
{
    QModelIndex newIndex = mapIndex(index, role);
    if (role == idRole
            || role == askedQuestionRole
            || role == answer1Role
            || role == answer2Role
            || role == answer3Role
            || role == answer4Role
            || role == correctAnswerRole
            || role == pictureRole) {

        return QIdentityProxyModel::data(newIndex, Qt::DisplayRole);
    }
    return QIdentityProxyModel::data(newIndex, role);
}

bool QuestionsProxyModel::addNewEntry(const QString &askedQuestion,
                                    const QString &answer1,
                                    const QString &answer2,
                                    const QString &answer3,
                                    const QString &answer4,
                                    int correctAnswer,
                                    const QString &picturePath)
{
    Q_ASSERT(!askedQuestion.isEmpty());
    Q_ASSERT(!answer1.isEmpty());
    Q_ASSERT(!answer2.isEmpty());
    Q_ASSERT(!answer3.isEmpty());
    Q_ASSERT(!answer4.isEmpty());
    Q_ASSERT(correctAnswer >= 1 && correctAnswer <= 4);


    auto newRow = rowCount();

    if(!insertRow(newRow, QModelIndex{})) {
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::id), newRow + 1)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::askedQuestion),
                           askedQuestion)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::answer1), answer1)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::answer2), answer2)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::answer3), answer3)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::answer4), answer4)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::correct_answer), correctAnswer)) {
        removeRow(newRow);
        return false;
    }
    if(!setData(index(newRow, QuestionColumn::picture), picturePath)) {
        removeRow(newRow);
        return false;
    }
    return true;
}

QModelIndex QuestionsProxyModel::mapIndex(const QModelIndex &source, int role) const
{
    switch(role) {
    case idRole:
        return createIndex(source.row(), QuestionColumn::id);
    case askedQuestionRole:
        return createIndex(source.row(), QuestionColumn::askedQuestion);
    case answer1Role:
        return createIndex(source.row(), QuestionColumn::answer1);
    case answer2Role:
        return createIndex(source.row(), QuestionColumn::answer2);
    case answer3Role:
        return createIndex(source.row(), QuestionColumn::answer3);
    case answer4Role:
        return createIndex(source.row(), QuestionColumn::answer4);
    case correctAnswerRole:
        return createIndex(source.row(), QuestionColumn::correct_answer);
    case pictureRole:
        return createIndex(source.row(), QuestionColumn::picture);
    }
    return source;
}

现在,如果我使用方法QuestionsProxyModel::addNewEntry,我希望所有这些数据都会被添加到SQL数据库中,但事实并非如此。

奇怪的是,在QML的视图中,我可以看到添加的数据,但在关闭应用程序时,它并没有存储在数据库中。除了使用insertRowsetData保存到数据库之外,我还需要做些什么吗?

此外,addNewEntry只在第一次使用时才有效。第二次insertRow只是返回false。

EN

回答 1

Stack Overflow用户

发布于 2020-10-26 01:30:24

我发现只有在调用submit时,数据才会保存到QSqlTableModel的数据库中。

所以我在addNewEntry of QuestionsProxyModel的末尾加上了

代码语言:javascript
复制
auto sqlModel = qobject_cast<QSqlTableModel*>(sourceModel());
if(sqlModel) {
    sqlModel->submit();
}

我觉得这个解决方案有点老生常谈。至少,如果底层模型不是QSqlTableModel,那么QuestionsProxyModel仍然可以正常工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64522739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档