Question

I'm trying to show an image in a QTreeView together with some other data. To to this I've created an QAbstractItemModel. In the data method, I return some strings for column index 0 and 1 and for the third I wish to return an image. This image however, is not being displayed.

When I return the image as a decoration it displays fine but I wish to add click listeners to the image that will trigger some events. I also wish to position my image to the far right in the treeview and this seems to require a custom delegate. For these reasons I've created a separate column for the image instead.

Image is created in constructor like this: mEditImage = QImage(":/images/myImage.png");

MyModel

QVariant MyModel::data(const QModelIndex &index, int role)  const {
    if (!index.isValid()) {
        return QVariant();
    }

    if(role == Qt::FontRole) {
        return fontData(index);
    }

    if(role == Qt::ForegroundRole) {
        return foreGroundData(index);
    }


    MyModelItem *item = getItem(index);

    /*
     * Use decoration to display image. Probably needs a
     * custom delegate to be able to position the image correctly.
     * (http://www.qtcentre.org/threads/49639-decoration-position-and-alignment)
     * (https://qt-project.org/forums/viewthread/24493)
     *
     * Will use extra column for now instead. Might help with click
     * listeners as well.
     *
     * if(role == Qt::DecorationRole && item->parent() != mRootItem) {
        return index.column() == 1 ? mEditImage : QVariant();
    }*/

    if(role == Qt::SizeHintRole) {
        return mEditImage.size();
    }

    if (role == Qt::DisplayRole) {

        QString id = QString::number(item->id());
        QString name = item->name();

        if(item->parent() != mRootItem && index.column() == 2) {
            return mEditImage;
        }

        if(item->parent() == mRootItem){
            return index.column() == 0 ? name : "";
        } else {
            return index.column() == 0 ? id : name;
        }
    } else if(role == Qt::BackgroundRole) {
        return QVariant();
    }

I've had a look here:

http://www.qtcentre.org/threads/29550-How-do-I-display-a-picture-on-a-QTableView-cell

How to set an image for a row?

I've tried changing the image to a QPixmap and QIcon and also tried embedding it in a QLabel (which could not be converted to a QVariant) without luck. Changing the image to a QString displays the string so the row/column logic seems fine. Removing the SizeHintRole logic doesn't make any difference either.

Any help in understanding how to display image data in a QTreeView would be helpful. I seem to be going at this from the wrong direction.

Cheers.

Was it helpful?

Solution

It doesn't matter, how to store image. QPixmap is prefferable for speed drawing.

QVariant MyModel::data(const QModelIndex &index, int role) const
{
 item = itemFromIndex( index ); // Your item implementation
 ...
 case Qt::DisplayRole:
   return item->getText();
 case Qt::DecorationRole:
   return item->getImage();
}

Read Qt docs about roles, it's good - http://doc.qt.io/qt-4.8/qt.html#ItemDataRole-enum

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top