2

所以我之前一直在浏览关于这个问题的先前问题,但我找不到我的代码的解决方案。

cpp file of dialog
------------------------------------------------
#include "everesult.h"
#include "ui_everesult.h"

everesult::everesult(QWidget *parent) :
    QDialog(parent),
    ui1(new Ui::everesult)
{
    ui1->setupUi(this);
}

everesult::~everesult()
{
    delete ui1;
}

void everesult::setmodel(QStandardItemModel *model)
{
    ui1->listView->setModel(model);
}

void everesult::on_buttonBox_clicked(QAbstractButton *button)
{
    EveReprocess M_;
    QModelIndex Selectedindex = ui1->listView->currentIndex();
    QModelIndex StationIdsindex = ui1->listView->model()->index(0, 1);

    int typeID = 0;
    int stationID = 0;
    stationID = ui1->listView->model()->data(StationIdsindex, Qt::DisplayRole).toInt();
    typeID = ui1->listView->model()->data(Selectedindex, Qt::DisplayRole).toInt();
    M_.GetMaterials(typeID, stationID);
}
--------------------------------------------------
Getmaterial and replyFinished from main window.
--------------------------------------------------

void EveReprocess::GetMaterials(int typeId, int stationid)
{
    //get typeid from material list
    this->modelMaterial = new QSqlQueryModel();
    modelMaterial->setQuery(QString("SELECT tm.quantity, tm.materialTypeID, t.typeName FROM invTypeMaterials tm INNER JOIN invTypes t ON t.TypeID = tm.materialTypeId WHERE tm.TypeID=%1 ").arg(typeId));
    if (!modelMaterial->query().exec())
        qDebug() << modelMaterial->query().lastError();

    //Set eve Central Url with typeids
    QUrl url = QUrl("http://api.eve-central.com/api/marketstat?");
    QUrlQuery q;
    int numRows = modelMaterial->rowCount();
    for (int row = 0; row < numRows; ++row)
    {
        QModelIndex index = modelMaterial->index(row, 1);
        q.addQueryItem( QString("typeid"), QString::number(modelMaterial->data(index, Qt::DisplayRole).toInt()));
    }
    q.addQueryItem( QString("usesystem"), QString::number(stationid));

    //set created url and connect
    url.setQuery(q);
    qDebug() << url;    
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply *)));
    manager->get(QNetworkRequest(url) );
}

void EveReprocess::replyFinished(QNetworkReply *reply)
{
    qDebug() << "replyFinished called";
    if ( reply->error() != QNetworkReply::NoError ) {
        qDebug() << "Request failed, " << reply->errorString();
        emit replyFinished(false);
        return;
    }
    qDebug() << "Request succeeded";
    //process with xmlreader and get values
    processSearchResult( reply);
}

一些代码在这里,我认为它应该在这里的某个地方,因为其余的工作正常。

这个问题出现在我使用对话框让用户从列表中选择一个 int 之后。

下面是调用我为此创建的对话框的函数。对不起,代码格式会在它工作后清理它

void EveReprocess::Search_TypeId(QString ItemName, QString SystemName)
{    
    QList<int> TypeIdList;
    QList<int> StationIdList;
    modelIds = new QStandardItemModel(10,2,this);
    if !(db.isOpen()) return;

    this->queryItem = new QSqlQuery;
    queryItem->prepare("SELECT typeID FROM invTypes WHERE invTypes.typeName LIKE ? AND invTypes.groupID NOT IN (268,269,270)AND published= 1");
    ItemName.prepend("%");
    ItemName.append("%");
    queryItem->bindValue(0, ItemName);

    this->queryStation = new QSqlQuery;
    queryStation->prepare("SELECT solarSystemID FROM mapSolarSystems WHERE mapSolarSystems.solarSystemName LIKE ?");
    SystemName.prepend("%");
    SystemName.append("%");
    queryStation->bindValue(0, SystemName);

    if(!queryStation->exec() || !queryItem->exec() )
    {
        qDebug() << queryItem->lastError().text();
        qDebug() << queryItem->lastQuery();
        qDebug() << queryStation->lastError().text();
        qDebug() << queryStation->lastQuery();
    }

    while( queryStation->next())
    {
        StationIdList.append(queryStation->value(0).toInt());
    }

    while(queryItem->next())
    {
        TypeIdList.append(queryItem->value(0).toInt());
    }


    for (int i = 0; i < StationIdList.count(); ++i)
    {
        modelIds->setItem(i,1,new QStandardItem(QString::number(StationIdList.at(i))));
    }

    for (int i = 0; i < TypeIdList.count(); ++i)
    {
        modelIds->setItem(i,0,new QStandardItem(QString::number(TypeIdList.at(i))));
    }


    //
    everesult Dialog;
    Dialog.setmodel(modelIds);
    Dialog.exec();
}
4

1 回答 1

2

在您继续之前,您的一些代码允许SQL 注入。即使它不是安全漏洞,它仍然会导致错误。您应该使用绑定,而不是在 SQL 查询中使用字符串替换。

你的问题在这里:

everesult Dialog;
Dialog.setmodel(modelIds);
Dialog.exec();

exec()是一个阻塞函数——它阻塞主事件循环,直到对话框被关闭。因此,来自线程网络访问管理器的信号永远不会传递给您的对象。

您应该异步显示对话框,如下所示:

everesult * dialog = new everesult;
dialog->setModel(modelIds);
dialog->show();
connect(dialog, SIGNAL(accepted()), dialog, SLOT(deleteLater());
connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater());

请注意,类型名称以小写开头,变量名称以大写开头是误导性的。Qt 的约定正好相反,除非您有充分的理由不这样做,否则保留它很有用。

SQL 查询中的 DO 参数绑定

QSqlQuery query("SELECT .. WHERE tm.TypeID=:typeid");
query.bindValue(":typeid", typeId);
QSqlQueryModel model;
model.setQuery(query);

不要在 SQL 查询中进行字符串替换

setQuery(QString("SELECT ... WHERE tm.TypeID=%1 ").arg(typeId));
于 2013-09-05T19:34:43.740 回答