Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSqlQueryModel and QPixmap's alignment



  • Hello,
    To display a Qpixmap in a QSqluerymodel (of a QTableView), I derive a QSqlQueryModel as follows:

    QVariant cSqlQueryModel::data(const QModelIndex &item, int role) const
    {if(item.column() == 5 && (role == Qt::DecorationRole || role == Qt::SizeHintRole))
        {
            QPixmap pixmapY(":/icon/yes.png" );
            QSqlRecord rec = record(item.row());
            int idx = rec.indexOf("xxactif");
            if (rec.value(idx) == 1)
            {
                if(role == Qt::DecorationRole)
                    return pixmapY;
    
                if(role == Qt::SizeHintRole)
                    return pixmapY.size();
            }
    
        return QSqlQueryModel::data(item,role);
    }
    

    It works fine but I would like to center the QPixmap in its column. Is there a way to do that?
    Thank you. Regards. Gilles



  • I think you are just using the wrong tool for the job. You shouldn't subclass the model, the delegate is the one to do this job:

    class YesDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
        Q_DISABLE_COPY(YesDelegate)
    public:
        explicit YesDelegate(QObject *parent = Q_NULLPTR)
            : QStyledItemDelegate(parent)
            , pixmapY(":/icon/yes.png")
        {}
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            if(index.data().toInt()==1){
                const QWidget * const widget = option.widget;
                QStyle * const style = widget ? widget->style() : QApplication::style();
                style->drawItemPixmap(painter,option.rect(),Qt::AlignCenter,pixmapY);
                return;
            }
            QStyledItemDelegate::paint(painter,option,index);
        }
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            if(index.data().toInt()==1)
                return pixmapY.size();
            return QStyledItemDelegate::sizeHint(option,index);
        }
    private:
        QPixmap pixmapY;
    };
    

    Now you can use a plain QSqlQueryModel and call tableview->setItemDelegateForColumn(5,new YesDelegate(tableview));



  • @Selzig
    Apart from what @VRonin suggests you change over to, for the record:

    It works fine

    How does:

    QPixmap pixmapY(":/icon/yes.png" );
    ...
                if(role == Qt::DecorationRole)
                    return pixmapY;
    

    work, given that pixmapY is a local variable on the stack and goes out of scope/gets destructed at the end of your function?



  • @JonB said in QSqlQueryModel and QPixmap's alignment:

    given that pixmapY is a local variable on the stack and goes out of scope/gets destructed at the end of your function?

    That method returns a QVariant the implicit constructor of QVariant called here will take a copy of it. In any case, variables allocated on the stack are kept alive across function returns (so even if it was a function returning QPixmap it would have been correct, if it returned QPixmap& or QPixmap* then it would have been a problem)



  • @VRonin
    Oh, I didn't know QVariant takes a copy, I thought it would "point to" an object! What, a copy of the actual pixmap, which could be MBs large?

    In any case, variables allocated on the stack are kept alive across function returns

    I didn't know/keep forgetting that one in C++ too! :(



  • @JonB said in QSqlQueryModel and QPixmap's alignment:

    What, a copy of the actual pixmap, which could be MBs large?

    As most of Qt classes, QPixmap is implicitly shared so the copy is very cheap



  • @VRonin
    OK, thanks, and I saw the list of which objects are shared on that doc page.
    I'll have to get my head around remembering Qt's sharing, and then C++ vs Python reference rules on top of that. Sigh, makes my head hurt :)



  • @VRonin : Your solution is much more effective. Thank you for your help. Have a good day. Gilles


Log in to reply