0

我有一个哈希映射,其值是一个名为 ModelBinding 的类的列表(qlist)。这个类有三个属性,我改变了其中一个:value。出于我不明白的原因,我的代码正在复制对象并修改该副本,而相反,我希望它修改该实例而不复制它。

问题

在我看来,我正在取消引用该对象并更改它。但是,很明显,更改的是副本而不是实例。这是为什么?我该如何更改实例?

代码

这是修改(或应该)实例值的函数:

void SqlQueryModel::updateBindings(QString modelName, QString col, QVariant val)
{
    qDebug() << "Got signal from model" << modelName << "col"<<col<<"changed to"<< val;

    /** Now, let's go through all the models associated to this instance.
     * We're going to see if the new signal we got is used for this model (for model name and column name).
     * If so, we'll assigned it (cf. annotation A1). Then, we'll execute this query by calling exec().
    **/

    bool anyValueChanged = false;

    QHash<QString, QList<ModelBinding> >::iterator bindingsIt;
    for (bindingsIt = bindings.begin(); bindingsIt != bindings.end(); bindingsIt++){

        QList<ModelBinding>::iterator eachBindingIt;
        QList<ModelBinding> curBinding = bindingsIt.value();

        for(eachBindingIt = curBinding.begin(); eachBindingIt != curBinding.end(); eachBindingIt++){
            ModelBinding binding = *eachBindingIt;
            if(bindingsIt.key() == modelName && binding.column == col){
                binding.value = val;
                binding.hasBeenChanged = true;
                anyValueChanged = true;
            }
        }
    }
    if (anyValueChanged){
        this->exec();
    }
}

这是 exec 函数,如果 anyValueChanged 为 true,则调用该函数:

void SqlQueryModel::exec()
{
    /* Let's create a QSqlQuery. It will store the query and we'll bind values to it.*/
    QSqlQuery sQuery;
    /* If we initialize the query with the string, then we CANNOT use bind (won't work and won't show any error).*/
    sQuery.prepare(this->query);

    /** Now, let's go through all the models associated to this instance.
     * For each of them, we'll bind its value.
    **/

    QHash<QString, QList<ModelBinding> >::iterator bindingsIt;
    for (bindingsIt = bindings.begin(); bindingsIt != bindings.end(); bindingsIt++){
        QList<ModelBinding>::iterator eachBindingIt;
        QList<ModelBinding> curBinding = bindingsIt.value();

        for(eachBindingIt = curBinding.begin(); eachBindingIt != curBinding.end(); eachBindingIt++){
            ModelBinding binding = *eachBindingIt;
            binding.bindToQuery(&sQuery);
        }
    }

    /* Let's not forget to execute this query, or nothing will be displayed in the QML. */
    sQuery.exec();
    qDebug() << sQuery.lastQuery();
    QMapIterator<QString, QVariant> i(sQuery.boundValues());
    while (i.hasNext()) {
        i.next();
        qDebug() << i.key().toAscii().data() << "="
                 << i.value().toString().toAscii().data();
    }
    this->setQuery(sQuery);
}

这是之前调用的名为 bindToQuery 的函数:

void ModelBinding::bindToQuery(QSqlQuery *sQuery)
{
    sQuery->bindValue(placeholder, value);
    qDebug() << "changed?" << hasBeenChanged;
    if(sQuery->boundValue(placeholder) != value){
        qDebug() << "Binding error: " << sQuery->boundValue(placeholder) << "!="
                 << value << "for" << placeholder;
    }else{
        qDebug() << placeholder << "binding successful with value"<<value;
    }
}

从调试消息中,值显然永远不会改变:

Got signal from model "tcModel" col "TLM_NO" changed to QVariant(QString, "AC00100") 
changed? true 
":tm" binding successful with value QVariant(QString, "AC01040") 
"SELECT * from tl04 WHERE TLM_NO=:tm" 
:tm = AC01040 
Generating role names. 
No error with query:
 "SELECT * from tl04 WHERE TLM_NO=?" 
4

1 回答 1

1
QList<ModelBinding> curBinding = bindingsIt.value();
...
ModelBinding binding = *eachBindingIt;

在编辑对象之前,您正在制作对象的副本。采用:

QList<ModelBinding>& curBinding = *bindingsIt;
...
ModelBinding& binding = *eachBindingIt;
于 2013-06-14T10:39:43.743 回答