【问题标题】:SQL Parameter count mismatch on QTableViewQTableView 上的 SQL 参数计数不匹配
【发布时间】:2019-07-26 10:30:21
【问题描述】:

我有一个由以下组成的 GUI:

N.1 图形视图

N.1 QTableView

双击 QTableView 的每一行后,用户根据需要打开的 N.1 对话框

我可以通过单击鼠标来捕获 QGraphicsView 上的特征。绘制特征后,我右键单击并打开如图所示的对话框:

点击接受后:我将特征注册为 QTableView 的行索引,如下所示:

如果我双击每一行,我可以再次打开包含先前保存的信息的相同对话框。我这样做是因为我可能需要更改图像的名称并以不同的方式调用它。

我目前遇到的问题是我从编译器收到了一个奇怪的Parameter count mismatch,我不明白为什么,这应该是由于QSQLITE

下面是我正在尝试做的代码中最重要的部分:

parameters.h

typedef struct Param
{
    int mId;
    QString mName;
    QByteArray mSave;
} Param;

class Parameters
{
public:
    Parameters() = default;
    Parameters(Param newdata);
    Parameters(int id, const QString &name, const QByteArray &save);
    int id() const { return data.mId; }
    QString name() const {return data.mName; }
    QByteArray save() const {return data.mSave; }
    Param getData() const { return data; }
    void setData(Param ndat) { data = ndat; }
private:
    Param data;
};

parameters.cpp

#include "parameters.h"
Parameters::Parameters(Param newdata) {
    data = newdata;
}
Parameters::Parameters(int id, const QString &name,
                               const QByteArray &save) {
    data.mId = id;
    data.mSave = save;
    data.mName = name;
}

数据库设置在以下dataleftcamera.h部分:

public:
    explicit dataLeftCamera(QObject *parent = nullptr);
    bool addItem(Parameters* mParameters);
    bool updateItem(int itemId, Parameters* mParameters);
    QSqlDatabase getDatabase();
private:
    QString mError;
    QSqlDatabase mDatabaseLeft;

该表是在 dataleftcamera.cpp 上启动的,这里是编译器在函数 updateItem 上给出 Parameter count mismatch 错误的地方

#define CREATE_TABLE \
    " CREATE TABLE IF NOT EXISTS leftCamTable" \
    " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL" \
    ", name TEXT NOT NULL" \
    ", save BLOB NOT NULL)"

dataLeftCamera::dataLeftCamera(QObject *parent) : QObject (parent)
{}

bool dataLeftCamera::addItem(Parameters *mParameters)
{
    QSqlQuery qry;
    qry.prepare("INSERT INTO leftCamTable (name, save)"\
                " VALUES (?,?)");
    qry.addBindValue(mParameters->name());
    qry.addBindValue(mParameters->save());

    bool ok = qry.exec();
    if(!ok) {
        mError = qry.lastError().text();
        qDebug() << mError;
    }
}

bool dataLeftCamera::updateItem(int itemId, Parameters *mParameters)
{
    QSqlQuery qry;
    qry.prepare(" UPDATE lefCamTable SET " \
                " name = ?," \
                " save = ?" \
                " WHERE id = ?");
    qry.addBindValue(mParameters->name());
    qry.addBindValue(mParameters->save());
    qry.addBindValue(itemId);

    bool ok = qry.exec();
    if(!ok) {
        mError = qry.lastError().text();
        qDebug() << mError;
    }
}

ma​​inwindow.cpp 上是我在行上doubleclick 更改图像名称并再次接受修改后更新项目的部分:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mDatabaseLeftCamera = new dataLeftCamera(this);
    mModelLeftCamera = nullptr;
    mModelLeftCamera = new QSqlTableModel(this);
    ui->tableView->setModel(mModelLeftCamera);
    connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)),
            this, SLOT(onTableClick(QModelIndex)));
// temporary folder
    temporaryFolder = "/home/name/Desktop/tempDBFolder/tmp.db";
    QFile dbRem(temporaryFolder);
    dbRem.remove();
    mDatabaseLeftCamera->inizializationDatabaseLeftCamera(temporaryFolder);
    mDatabaseLeftCamera->configurationDatabaseLeftCamera();
    mModelLeftCamera = new QSqlTableModel(this, mDatabaseLeftCamera->getDatabase());
    mModelLeftCamera->setTable("leftCamTable");
    mModelLeftCamera->select();
    ui->tableView->setModel(mModelLeftCamera);
    ui->tableView->showColumn(true);
}

// opening the dialog for the first time after capturing the image
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    // operations

    Param result = d.getData();
    Parameters* param = new Parameters(result);
    mDatabaseLeftCamera->addItem(param);
    mModelLeftCamera->select();
    ui->tableView->show();
}

// This is the doubleclick that re-opens the small dialog to change the name of the feature

void MainWindow::onTableClick(const QModelIndex &index)
{
    int row = index.row();
    Param currentData;
    int ItemId = index.sibling(row, 0).data().toInt();
    currentData.mName = index.sibling(row, 1).data().toString();
    currentData.mSave = index.sibling(row, 2).data().toByteArray();
    QPixmap iconPix;
    if(!iconPix.loadFromData(index.sibling(row, 2).data().toByteArray())) {
    }
    clipSceneDialog d(this);
    d.show();
    d.setData(currentData);
    d.setImage(iconPix.toImage());

    if(d.exec() == QDialog::Rejected) {
        return;
    } else {
        //
    }
    Param result = d.getData();
    Parameters* param = new Parameters(result);
    mDatabaseLeftCamera->updateItem(ItemId,param);
    mModelLeftCamera->select();
    ui->tableView->show();
}

如果有帮助,请查看编译器给出的错误:

如果这是微不足道的,我很抱歉,但我检查了updateItem(ItemId,param) 并感谢您阐明这一点。

【问题讨论】:

  • 对我来说,上一张图片中的这些消息看起来像运行时消息,但不是编译器错误。我在 SQL 方面没有经验,但看起来您的 SQL 检索不正确。顺便提一句。请复制/粘贴控制台输出和其他日志文本作为文本,而不是制作快照。
  • OT.: 你的应用。快照让我想,您正在为编码问题而苦苦挣扎。 (我的意思是表中PNG 之前和之后的有趣字形。)关于编码问题,有一个很好的介绍:About Unicode and Character SetsQString 有很多 tofrom 函数来解决这个问题 - 你只需要正确使用它们。

标签: c++ sql sqlite qt5 qtableview


【解决方案1】:

尝试添加一些调试打印。特别是对于您添加到准备好的语句中的参数。 qry.addBindValue 将您的值转换为 QVariant。基于documentation QVariants 在它们不包含数据时变为NULL

QVariant x(QString());
// x.isNull() == true

如果在检索参数时出现问题,这可以解释违反 NOT NULL 约束的原因。

【讨论】:

  • @Scheff - 感谢您的评论和花时间阅读问题!您在PNG 之前和之后看到的字形是故意的。原因是用户可能有数百张图像,向下滚动查看所有图像会冻结 GUI,并且需要很长时间才能到达终点。因此,快速浏览图像的一种好方法(虽然不优雅)不是保存图像。如果有更优雅和有效的方法,请告诉我。或者,如果您知道现有示例,请分享它们,因为它会有所帮助。
  • 也感谢@jschwing 抽出时间阅读问题!显然,这count mismatch 似乎是由于onTableClick 函数内的itemIdQTableView 内的用户doubleclick 所在的行不同。我拿了一个print screen 的调试器。 this 也有用吗?我不明白怎么做的。
  • 感谢 @jschwing 建议使用 QVariant x(QString()); 它有效。发生的事情是,只要我创建了一个引用,默认参数就会立即传递。所以nameLineEdit 已经有了一些东西并且违反了NOT NULL 约束。我会将您的答案标记为正确!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 2011-02-10
  • 1970-01-01
  • 2017-12-31
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多