Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Replacing image in QStyledItemDelegate
Qt 6.12 LTS is out! See what's new in the release blog

Replacing image in QStyledItemDelegate

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 3 Posters 6.8k Views 2 Watching
  • 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 samdol

    I think you have to reimplement
    void YourItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    function. You may need QApplication::style()->drawControl(QStyle::CE_Control, &button, painter); to allow user interacts with item so that she can change the im
    age.

    raven-worxR Offline
    raven-worxR Offline
    raven-worx
    Moderators
    wrote on last edited by raven-worx
    #3

    @samdol said in Replacing image in QStyledItemDelegate:

    You may need QApplication::style()->drawControl(QStyle::CE_Control, &button, painter); to allow user interacts with item so that she can change the image.

    Sorry but that is not true. As the method-name already implies, this only draws a control. So no interaction handling.

    To change the icon persistently you need to update the icon in the model - e.g. by using setData(index, QVariant::fromValue<QPixmap>(...), Qt::DecorationRole). If the model is correctly implemented the icon is updated automatically.

    If you just want to paint a different icon but leave the actual data unchanged do this:

    void MyItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
    {
              QStyledItemDelegate::initStyleOption(option, index);
    
              if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option))  {
                       if( v4->features & QStyleOptionViewItemV2::HasDecoration )
                                v4->icon = QIcon(...);
              }
    }
    

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    G 2 Replies Last reply
    4
    • raven-worxR raven-worx

      @samdol said in Replacing image in QStyledItemDelegate:

      You may need QApplication::style()->drawControl(QStyle::CE_Control, &button, painter); to allow user interacts with item so that she can change the image.

      Sorry but that is not true. As the method-name already implies, this only draws a control. So no interaction handling.

      To change the icon persistently you need to update the icon in the model - e.g. by using setData(index, QVariant::fromValue<QPixmap>(...), Qt::DecorationRole). If the model is correctly implemented the icon is updated automatically.

      If you just want to paint a different icon but leave the actual data unchanged do this:

      void MyItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
      {
                QStyledItemDelegate::initStyleOption(option, index);
      
                if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option))  {
                         if( v4->features & QStyleOptionViewItemV2::HasDecoration )
                                  v4->icon = QIcon(...);
                }
      }
      
      G Offline
      G Offline
      gabor53
      wrote on last edited by
      #4

      @raven-worx
      Thank you. I actually want to change the icon and update the database with that icon.

      1 Reply Last reply
      0
      • raven-worxR raven-worx

        @samdol said in Replacing image in QStyledItemDelegate:

        You may need QApplication::style()->drawControl(QStyle::CE_Control, &button, painter); to allow user interacts with item so that she can change the image.

        Sorry but that is not true. As the method-name already implies, this only draws a control. So no interaction handling.

        To change the icon persistently you need to update the icon in the model - e.g. by using setData(index, QVariant::fromValue<QPixmap>(...), Qt::DecorationRole). If the model is correctly implemented the icon is updated automatically.

        If you just want to paint a different icon but leave the actual data unchanged do this:

        void MyItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
        {
                  QStyledItemDelegate::initStyleOption(option, index);
        
                  if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option))  {
                           if( v4->features & QStyleOptionViewItemV2::HasDecoration )
                                    v4->icon = QIcon(...);
                  }
        }
        
        G Offline
        G Offline
        gabor53
        wrote on last edited by
        #5

        @raven-worx
        My original idea was that when the image field is chosen I replace the original image with a QPushbutton. When the button is clicked it opens QFile and lets the user choose a different picture. Than the icon in the view is changed to the new image and the new image is saved into the db.

        raven-worxR 1 Reply Last reply
        0
        • G gabor53

          @raven-worx
          My original idea was that when the image field is chosen I replace the original image with a QPushbutton. When the button is clicked it opens QFile and lets the user choose a different picture. Than the icon in the view is changed to the new image and the new image is saved into the db.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #6

          @gabor53
          you can do this by creating a custom editor widget in createEditor(). Save the filepath (e.g. with setProperty("file-path")on the pushbutton, and read it again on save in setModelData(). In there you call model->setData().
          If not already done you of course need to implement setData() in your model to save the value (image,...) back to the DB.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          G 1 Reply Last reply
          2
          • raven-worxR raven-worx

            @gabor53
            you can do this by creating a custom editor widget in createEditor(). Save the filepath (e.g. with setProperty("file-path")on the pushbutton, and read it again on save in setModelData(). In there you call model->setData().
            If not already done you of course need to implement setData() in your model to save the value (image,...) back to the DB.

            G Offline
            G Offline
            gabor53
            wrote on last edited by
            #7

            @raven-worx
            I created the button in createEditor().

                        QPushButton *button = new QPushButton(parent) ;
                        button->setMaximumWidth (100);
            

            In setEditorData() I have

               QPushButton *button = qobject_cast<QPushButton*>(editor);
                if(button)
                    {
                        button->setIcon (QIcon("C:/Programming/Projects/Folkfriends_1_0/icons/fix.png"));
                    }
            

            .At this point I think I should have a button if the user clicks on the image but after clicking on the image I get a textEditor. What did I miss? Thank you.

            raven-worxR 1 Reply Last reply
            0
            • G gabor53

              @raven-worx
              I created the button in createEditor().

                          QPushButton *button = new QPushButton(parent) ;
                          button->setMaximumWidth (100);
              

              In setEditorData() I have

                 QPushButton *button = qobject_cast<QPushButton*>(editor);
                  if(button)
                      {
                          button->setIcon (QIcon("C:/Programming/Projects/Folkfriends_1_0/icons/fix.png"));
                      }
              

              .At this point I think I should have a button if the user clicks on the image but after clicking on the image I get a textEditor. What did I miss? Thank you.

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #8

              @gabor53
              show the whole createEditor() method pls.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              G 2 Replies Last reply
              0
              • raven-worxR raven-worx

                @gabor53
                show the whole createEditor() method pls.

                G Offline
                G Offline
                gabor53
                wrote on last edited by
                #9

                @raven-worx
                I found the problem. The correct code is

                 QPushButton *button = qobject_cast<QPushButton*>(editor);
                    if(button)
                        {
                            button->setIcon (QIcon("C:/Programming/Projects/Folkfriends_1_0/icons/fix.png"));
                return button;
                        }
                

                I missed the return...

                raven-worxR 1 Reply Last reply
                0
                • raven-worxR raven-worx

                  @gabor53
                  show the whole createEditor() method pls.

                  G Offline
                  G Offline
                  gabor53
                  wrote on last edited by
                  #10

                  @raven-worx
                  My next step (as I have the button now) is to place the original image on the button.
                  In setEditorData I have the following:

                  QPushButton *button = qobject_cast<QPushButton*>(editor);
                      if(button)
                          {            
                              QPixmap buttonPix;
                              buttonPix.loadFromData (index.model ()->data (index,Qt::DisplayRole).toByteArray ());
                  
                              qDebug() << "Fix image size: " << buttonPix.size();
                  
                              button->setIcon (QIcon(buttonPix));
                  
                          }
                  

                  I hoped to create a QPixmap from the BLOB in the database located where the index points. I wanted to place the pixmap on the button as an icon. The button is still there but the original image is not on the button and I also got the message
                  Fix image size: QSize(0, 0)
                  which shows my QPixmap is empty. What step did I miss? Thank you.

                  1 Reply Last reply
                  0
                  • G gabor53

                    @raven-worx
                    I found the problem. The correct code is

                     QPushButton *button = qobject_cast<QPushButton*>(editor);
                        if(button)
                            {
                                button->setIcon (QIcon("C:/Programming/Projects/Folkfriends_1_0/icons/fix.png"));
                    return button;
                            }
                    

                    I missed the return...

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #11

                    @gabor53 said in Replacing image in QStyledItemDelegate:

                    I missed the return...

                    yes, i was suspecting that.

                    @gabor53 said in Replacing image in QStyledItemDelegate:

                    I hoped to create a QPixmap from the BLOB in the database located where the index points

                    basically your code looks correct.
                    Whats the image format of the image blob?
                    Does your model's data() method really return a QByteArray for the Qt::DisplayRole?
                    Please show your data() implementation.

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    G 2 Replies Last reply
                    0
                    • raven-worxR raven-worx

                      @gabor53 said in Replacing image in QStyledItemDelegate:

                      I missed the return...

                      yes, i was suspecting that.

                      @gabor53 said in Replacing image in QStyledItemDelegate:

                      I hoped to create a QPixmap from the BLOB in the database located where the index points

                      basically your code looks correct.
                      Whats the image format of the image blob?
                      Does your model's data() method really return a QByteArray for the Qt::DisplayRole?
                      Please show your data() implementation.

                      G Offline
                      G Offline
                      gabor53
                      wrote on last edited by
                      #12

                      @raven-worx
                      The image format is jpg.
                      I believe the model's data() method returns a QByteArray, but here is the code:
                      The function that saves the image to the db:

                      QFile fileReview(fileNameChosen);
                      
                          if(fileReview.open (QIODevice::ReadOnly))
                              {
                                  fileByteArray = fileReview.readAll ();
                              }
                      
                      QFile fileReview(fileNameChosen);
                      
                          if(fileReview.open (QIODevice::ReadOnly))
                              {
                                  fileByteArray = fileReview.readAll ();
                              }
                      

                      The model's data() implementation:

                       QStandardItemModel *fixModel = new QStandardItemModel(this);
                          ui->tableView_Fix->setModel (fixModel);
                      
                          for(int row1 = 0; query_fix.next (); row1++)
                              {
                                  if(row1 == 0)
                                      {
                                          const QSqlRecord qRec = query_fix.record();
                                          qDebug() << "The number of records (MainWindow): " << qRec;
                                          fixModel->insertColumns (0, qRec.count());
                                          qDebug() << "fixdb record count: " << qRec.count ();
                                      }
                      
                                  fixModel->insertRow (row1);
                                  fixModel->setData (fixModel->index (row1,0),query_fix.value (0));
                                  fixModel->setData (fixModel->index (row1,1),query_fix.value (1));
                                  fixModel->setData (fixModel->index (row1,2), query_fix.value (13));
                      
                                  fixPixmap.loadFromData (query_fix.value (2).toByteArray ());
                                  fixPixmap = fixPixmap.scaled (100,100,Qt::KeepAspectRatio);
                      
                                  fixModel->setData (fixModel->index (row1,3),fixPixmap,Qt::DecorationRole);
                                  fixModel->setData (fixModel->index (row1,4),query_fix.value (11));
                                  fixModel->setData (fixModel->index (row1,5),query_fix.value (10));
                                  fixModel->setData (fixModel->index (row1,6),query_fix.value (3));
                                  fixModel->setData (fixModel->index(row1,7),query_fix.value (4));
                                  fixModel->setData (fixModel->index (row1,8),query_fix.value (12));
                                  fixModel->setData (fixModel->index (row1,9),query_fix.value (7));
                                  fixModel->setData (fixModel->index (row1,10),query_fix.value (8));
                                  fixModel->setData (fixModel->index (row1,11),query_fix.value (9));
                      
                                  ui->tableView_Fix->setRowHeight (row1,100);
                              }
                      
                      

                      Thank you.

                      1 Reply Last reply
                      0
                      • raven-worxR raven-worx

                        @gabor53 said in Replacing image in QStyledItemDelegate:

                        I missed the return...

                        yes, i was suspecting that.

                        @gabor53 said in Replacing image in QStyledItemDelegate:

                        I hoped to create a QPixmap from the BLOB in the database located where the index points

                        basically your code looks correct.
                        Whats the image format of the image blob?
                        Does your model's data() method really return a QByteArray for the Qt::DisplayRole?
                        Please show your data() implementation.

                        G Offline
                        G Offline
                        gabor53
                        wrote on last edited by
                        #13

                        @raven-worx
                        I also noticed, that for some reason all the images are saved 45 degrees turned right so all the vertical images are horizontal.

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          gabor53
                          wrote on last edited by
                          #14

                          Ran the debugger and got the following at this line:

                               QPixmap buttonPix;
                                      buttonPix.loadFromData (index.model ()->data (index,Qt::DisplayRole).toByteArray ());
                          

                          In the Locals and Expressions window I got the following Name - Value - Type values:
                          buttonPix - (invalid) - QPixmap.
                          I'm wondering why is it invalid? (Or what can make it invalid?)
                          Thank you.

                          raven-worxR 1 Reply Last reply
                          0
                          • G gabor53

                            Ran the debugger and got the following at this line:

                                 QPixmap buttonPix;
                                        buttonPix.loadFromData (index.model ()->data (index,Qt::DisplayRole).toByteArray ());
                            

                            In the Locals and Expressions window I got the following Name - Value - Type values:
                            buttonPix - (invalid) - QPixmap.
                            I'm wondering why is it invalid? (Or what can make it invalid?)
                            Thank you.

                            raven-worxR Offline
                            raven-worxR Offline
                            raven-worx
                            Moderators
                            wrote on last edited by raven-worx
                            #15

                            @gabor53
                            you are already returning a QPixmap (fixModel->setData (fixModel->index (row1,3),fixPixmap,Qt::DecorationRole);) not a QByteArray

                            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                            If you have a question please use the forum so others can benefit from the solution in the future

                            G 1 Reply Last reply
                            0
                            • raven-worxR raven-worx

                              @gabor53
                              you are already returning a QPixmap (fixModel->setData (fixModel->index (row1,3),fixPixmap,Qt::DecorationRole);) not a QByteArray

                              G Offline
                              G Offline
                              gabor53
                              wrote on last edited by
                              #16

                              @raven-worx
                              I tried to use

                              buttonPix.loadFromData (index.model ()->data (index,Qt::DisplayRole).toByteArray ());
                              

                              without toByteArray() but it didn't work. I assumed that the model stores the data as a QVariant so I tried to do the following:

                              QPixmap buttonPix;
                                          QVariant pic;
                                          pic = (index.data (Qt::DisplayRole));
                                          buttonPix.loadFromData (pic.toByteArray());
                              
                                          button->setIcon (QIcon(buttonPix));
                              
                                          int row = index.row ();
                                          int col = index.column ();
                              
                                          qDebug() << "SetEditorData row, col: " << "(" << row << "," << col << ")";
                              
                                          qDebug() << "Fix image size: " << buttonPix.size();          
                              
                                          return;
                              
                              

                              and the message I got was identical to the previous one:
                              QPixmap::scaled: Pixmap is a null pixmap
                              SetEditorData row, col: ( 1 , 3 )
                              Fix image size: QSize(0, 0)

                              After running Debug at the

                                QPixmap buttonPix;
                              
                              

                              line the buttonPix value was buttonPix (481622520x389579424) QPixmap
                              which changed to buttonPix (Invalid) QPixmap at the QVariant pic line. What am I missing here? Is this a completely incorrect idea? Thank you.

                              1 Reply Last reply
                              0

                              • Login

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