Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSqlQueryModel and QPixmap's alignment
Forum Updated to NodeBB v4.3 + New Features

QSqlQueryModel and QPixmap's alignment

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 5 Posters 1.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Selzig
    wrote on last edited by VRonin
    #1

    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

    JonBJ 1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      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));

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      C 1 Reply Last reply
      2
      • S Selzig

        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

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #3

        @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?

        VRoninV 1 Reply Last reply
        0
        • JonBJ JonB

          @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?

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          @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)

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          JonBJ 1 Reply Last reply
          1
          • VRoninV VRonin

            @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)

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by
            #5

            @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! :(

            VRoninV 1 Reply Last reply
            0
            • JonBJ JonB

              @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! :(

              VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              @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

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              JonBJ 1 Reply Last reply
              2
              • VRoninV VRonin

                @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

                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by
                #7

                @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 :)

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  Selzig
                  wrote on last edited by
                  #8

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

                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    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));

                    C Offline
                    C Offline
                    cawlfj
                    wrote on last edited by
                    #9

                    @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?

                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @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.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      2

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved