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



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

    QStyledItemDelegate

    hi VRonin

    when the QTableView cell contains "no" , how to set it red color in by YesDelegate?


  • Lifetime Qt Champion

    @cawlfj said in QSqlQueryModel and QPixmap's alignment:

    when the QTableView cell contains "no" , how to set it red color in by YesDelegate?

    You have all information about the content in the paint event. So check for the string in there and set the background color to red.


Log in to reply