Search code examples
qtqmap

Qt Setting table entry changes value of QMap


I have an issue with a "table->setItem(index, 0, widg);" statement having unwanted side-effects.

I have a map of QStrings to QStrings:

QMap<QString, QString> levelPlist;

Later on, I have a function to fill a QTableWidget with the keys and values contained in this map. So, I have the following function:

void MainWindow::updateLevelPlistTable()
{
    QTableWidget *table = ui->levelPlistTableWidget;

    int count = levelPlist.count();
    table->setRowCount(count);
    table->setColumnCount(2);


    QMap<QString, QString>::const_iterator i;
    int index = 0;

    for (i = levelPlist.constBegin(); i != levelPlist.constEnd(); ++i)
    {
        qDebug(QString("BG TEX pre  - " + levelPlist.value("background_texture")).toAscii());
        QTableWidgetItem *widg = new QTableWidgetItem(i.key());
        qDebug(QString("BG TEX pre mid  - " + levelPlist.value("background_texture")).toAscii());
        table->setItem(index, 0, widg);
        qDebug(QString("BG TEX mid  - " + levelPlist.value("background_texture")).toAscii());
        table->setItem(index, 1, new QTableWidgetItem(i.value()));

        qDebug(QString("BG TEX post - " + levelPlist.value("background_texture")).toAscii());
        if(index == 0)
        {
            qDebug(QString("Key - " + i.key() + ", Value - " + i.value()).toAscii());
        }
        index++;
    }
}

Pardon all of the debugging text, but that's how I was able to narrow down exactly where the problem is. Here's some of the output from when the function runs ("background_texture" initially maps to "nope"):

BG TEX pre  - nope
BG TEX pre mid  - nope
BG TEX mid  - background_texture
BG TEX post - background_texture
Key - background_texture, Value - background_texture
BG TEX pre  - background_texture
BG TEX pre mid  - background_texture
BG TEX mid  - level_height
BG TEX post - 600
BG TEX pre  - 600
BG TEX pre mid  - 600
BG TEX mid  - level_width
BG TEX post - 400

As you can see, the value changes between the "pre mid" and "mid" debug statements, which means that executing the statement of "table->setItem(index, 0, widg);" changes the value of the "background_texture" key to whatever the latest i.value() is.

Why?

Edit: Full debug information:

void MainWindow::updateLevelPlistTable()
{
    QTableWidget *table = ui->levelPlistTableWidget;

    int count = levelPlist.count();
    table->setRowCount(count);
    table->setColumnCount(2);


    QMap<QString, QString>::const_iterator i;
    int index = 0;

    for (i = levelPlist.constBegin(); i != levelPlist.constEnd(); ++i)
    {
        QTableWidgetItem *widg = new QTableWidgetItem(i.key());
        table->setItem(index, 0, widg);
        qDebug() << "before - " << levelPlist;
        table->setItem(index, 1, new QTableWidgetItem(i.value()));
        qDebug() << "after - " << levelPlist << "\n";
        index++;
    }
}

produces

before -  QMap(("background_texture", "background_texture")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 
after -  QMap(("background_texture", "background_texture")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 

before -  QMap(("background_texture", "level_height")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 
after -  QMap(("background_texture", "600")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 

before -  QMap(("background_texture", "level_width")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 
after -  QMap(("background_texture", "400")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 

before -  QMap(("background_texture", "start_x")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 
after -  QMap(("background_texture", "250")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 

before -  QMap(("background_texture", "start_y")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 
after -  QMap(("background_texture", "50")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 

before -  QMap(("background_texture", "world")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 
after -  QMap(("background_texture", "null")("level_height", "600")("level_width", "400")("start_x", "250")("start_y", "50")("world", "null")) 

Solution

  • Can you show the debug output of the whole map every time instead of the value stored under the key? One reason for such a behaviour could be that some slot listens to a signal emitted by the table model and modifies the map.