Calvin
Calvin

Reputation: 2912

How can I extract the displayed text from a QTableWidgetItem?

I have a subclass of QTableWidget with the following code:

connect(this, SIGNAL(cellChanged(int, int)), this, SLOT(pushCellChange(int, int)), Qt::QueuedConnection);

...

void MyTableView::pushCellChange(int row, int column)
{
    QString text(item(row, column)->text());
    QByteArray data = text.toAscii();
    cout << data.length() << endl;
    const char* cellData = text.toAscii().constData();
    cout << "Cell ("<<row<<", "<<column<<") changed to: " << cellData << endl;
}

When I change the upper-right cell to anything this outputs:

2
Cell (0, 0) changed to: ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌░▬∟C▌▌

However, while this corrupt data is spewed out on the console, the table widget itself seems to behave normally and shows the correct string. Does anyone know what is going on here?

Upvotes: 0

Views: 605

Answers (3)

Tobias Leupold
Tobias Leupold

Reputation: 1754

If it's just about the console output, you could also use qDebug() (available after #include <QDebug>) and pass the QString directly:

void MyTableView::pushCellChange(int row, int column)
{
    qDebug() << item(row, column)->text().length();
    qDebug() << "Cell (" << row << ", " << column << ") changed to: "
             << item(row, column)->text();
}

This way, you don't have to mess with data conversion …

Upvotes: 0

tmpearce
tmpearce

Reputation: 12693

The call toAscii() is storing the QString's data to a QByteArray. In your code, you do this twice:

QByteArray data = text.toAscii();

const char* cellData = text.toAscii().constData();
                       _____________^ <-- temporary QByteArray   

The const char* is actually pointing to the data within a temporary variable, which goes out of scope at the semicolon, at which point the pointer becomes invalid. If instead you were to make use of the local variable data, you'd be OK:

const char* cellData = data.constData();
                       ___^ <-- still-in-scope QByteArray

Alternatively, you can do this all in-line with the cout and the data will still be valid when it is copied to the output stream:

cout << "Cell ("<<row<<","<<column<<") changed to: " << text.toAscii().constData() << endl;

Upvotes: 2

Lander
Lander

Reputation: 3437

std::string cellData = text.ToStdString();
cout << "Cell ("<<row<<", "<<column<<") changed to: " << cellData << endl;

That should work fine. As for why toAscii doesn't work, I have no clue.

Upvotes: 2

Related Questions