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. QStiledItemDelegate setModelData doesn't display image
Forum Updated to NodeBB v4.3 + New Features

QStiledItemDelegate setModelData doesn't display image

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 3 Posters 5.4k 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #14

    Apologies, I did not read the model was QSqlTableModel. You can put a proxy like this one (You'll have to add if(role==Qt::EditRole) return QIdentityProxyModel::setData(index,value,role); in line 29) in between to make the multiple roles work. On the other hand, you latest implementations of setModelData look like you do not completely understand how models work and you are panicking and try to mix a bunch of stuff together hoping that it works

    #include "fixviewdelegate.h"
    
    FixViewDelegate::FixViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {
      qDebug() << "Entered fixViewDelegate (1).";
    }
    
    QWidget* FixViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    
      qDebug() << "Entered createEditor";
      Q_UNUSED(option);
      Q_UNUSED(index);
    
    
      return new ImagePickButton(parent);
    
    
    }
    
    void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    
     QPixmap loadedImage=index.data(Qt::DecorationRole).value<QPixmap>();
    
    
     
    
      const QWidget* widget = option.widget;
    
    
      QStyle* style = widget ? widget->style() : QApplication::style();
      style->drawItemPixmap (painter, option.rect, Qt::AlignCenter, loadedImage);
    
    }
    
    void FixViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      Q_UNUSED(index);
      editor->setGeometry(option.rect);
    }
    
    void FixViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
    
      qDebug() << "Entered setEditorData.";
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
      Q_ASSERT(imgPick);
      imgPick->setSelectedFile(index.data(Qt::UserRole).toString());
    
    }
    
    void FixViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* fixModel, const QModelIndex& index) const {
      qDebug() << "Entered setModelData. ";
    
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
      Q_ASSERT(imgPick);
    
      QString value;
      value = imgPick->selectedFile ();
    
      QPixmap newImage(value);
    if(newImage.isNull()){
    fixModel->setData(index, QVariant(), Qt::DecorationRole);
    fixModel->setData(index, QVariant(), Qt::UserRole);
    return;
    }
      newImage = newImage.scaled (100, 100, Qt::KeepAspectRatio);
      qDebug() << "newImage size: " << newImage.size ();
    
      qDebug()  << "Index: " << index;
    
      fixModel->setData(index, newImage, Qt::DecorationRole);
    fixModel->setData(index, value, Qt::UserRole);
    }
    
    

    You will still need to use the proxy I linked above inbetween

    "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

    G 1 Reply Last reply
    1
    • VRoninV VRonin

      Apologies, I did not read the model was QSqlTableModel. You can put a proxy like this one (You'll have to add if(role==Qt::EditRole) return QIdentityProxyModel::setData(index,value,role); in line 29) in between to make the multiple roles work. On the other hand, you latest implementations of setModelData look like you do not completely understand how models work and you are panicking and try to mix a bunch of stuff together hoping that it works

      #include "fixviewdelegate.h"
      
      FixViewDelegate::FixViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {
        qDebug() << "Entered fixViewDelegate (1).";
      }
      
      QWidget* FixViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      
        qDebug() << "Entered createEditor";
        Q_UNUSED(option);
        Q_UNUSED(index);
      
      
        return new ImagePickButton(parent);
      
      
      }
      
      void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      
       QPixmap loadedImage=index.data(Qt::DecorationRole).value<QPixmap>();
      
      
       
      
        const QWidget* widget = option.widget;
      
      
        QStyle* style = widget ? widget->style() : QApplication::style();
        style->drawItemPixmap (painter, option.rect, Qt::AlignCenter, loadedImage);
      
      }
      
      void FixViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
        Q_UNUSED(index);
        editor->setGeometry(option.rect);
      }
      
      void FixViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
      
        qDebug() << "Entered setEditorData.";
        ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
        Q_ASSERT(imgPick);
        imgPick->setSelectedFile(index.data(Qt::UserRole).toString());
      
      }
      
      void FixViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* fixModel, const QModelIndex& index) const {
        qDebug() << "Entered setModelData. ";
      
        ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
        Q_ASSERT(imgPick);
      
        QString value;
        value = imgPick->selectedFile ();
      
        QPixmap newImage(value);
      if(newImage.isNull()){
      fixModel->setData(index, QVariant(), Qt::DecorationRole);
      fixModel->setData(index, QVariant(), Qt::UserRole);
      return;
      }
        newImage = newImage.scaled (100, 100, Qt::KeepAspectRatio);
        qDebug() << "newImage size: " << newImage.size ();
      
        qDebug()  << "Index: " << index;
      
        fixModel->setData(index, newImage, Qt::DecorationRole);
      fixModel->setData(index, value, Qt::UserRole);
      }
      
      

      You will still need to use the proxy I linked above inbetween

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

      @VRonin
      Thank you.
      I created a class named ExtraRolesProxyModel.
      I added

      #include "extrarolesproxymodel.h"
      

      to fixviewdelegate.h.
      My fixviewdelegate.cpp looks like this now:

      #include "fixviewdelegate.h"
      
      FixViewDelegate::FixViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {
        qDebug() << "Entered fixViewDelegate (1).";
      }
      
      QWidget* FixViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      
        qDebug() << "Entered createEditor";
        Q_UNUSED(option);
        Q_UNUSED(index);
      
      
        return new ImagePickButton(parent);
      
      
      }
      
      void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      
        if(role == Qt::EditRole) return;
        QIdentityProxyModel::setData(index, value, role);
      
        QPixmap loadedImage = index.data (Qt::DecorationRole).value<QPixmap>();
      
      //  loadedImage.loadFromData (index.data ().toByteArray ()) ;
      //  loadedImage = loadedImage.scaled (100, 100, Qt::KeepAspectRatio);
      
        const QWidget* widget = option.widget;
      
       QStyle* style = widget ? widget->style() : QApplication::style();
        style->drawItemPixmap (painter, option.rect, Qt::AlignCenter, loadedImage);
      }
      
      void FixViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
        Q_UNUSED(index);
        editor->setGeometry(option.rect);
      }
      
      void FixViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
      
        qDebug() << "Entered setEditorData.";
        ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
        Q_ASSERT(imgPick);
        imgPick->setSelectedFile(index.data(Qt::UserRole).toString());
      
      }
      
      void FixViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* fixModel, const QModelIndex& index) const {
        qDebug() << "Entered setModelData. ";
      
        ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
        Q_ASSERT(imgPick);
      
        QString value;
        value = imgPick->selectedFile ();
      
        QPixmap newImage(value);
        if(newImage.isNull ()) {
          fixModel->setData (index, QVariant(), Qt::DecorationRole);
          fixModel->setData (index, QVariant(), Qt::UserRole);
          return;
        }
      
      
        newImage = newImage.scaled (100, 100, Qt::KeepAspectRatio);
        qDebug() << "newImage size: " << newImage.size ();
      
        qDebug()  << "Index: " << index;
      
      //  if(fixModel->setData(index, newImage, Qt::EditRole) == true) {
      //    qDebug() << "Data IS set. ";
      //  } else {
      //    qDebug() << "Data is NOT set. ";
      //  };
      
        fixModel->setData (index, newImage, Qt::DecorationRole);
        fixModel->setData (index, newImage, Qt::UserRole);
      }
      

      When I build it it gives the following errors:
      'role' was not declared in this scope.
      'value' was not declared in this scope.
      Did I add the proxy incorrectly?

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

        That's a proxy model, it has nothing to do with the delegate. I have no idea why you merged the 2. I gave you the code of both the delegate and the proxy model. You just have to copy-paste them, add 1 single line I posted at the place I posted inside extrarolesproxymodel.h it and then use them

        "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

        G 1 Reply Last reply
        1
        • VRoninV VRonin

          That's a proxy model, it has nothing to do with the delegate. I have no idea why you merged the 2. I gave you the code of both the delegate and the proxy model. You just have to copy-paste them, add 1 single line I posted at the place I posted inside extrarolesproxymodel.h it and then use them

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

          @VRonin
          Is

          if(role == Qt::EditRole) return QIdentityProxyModel::setData(index, value, role);
          

          goes into extrarolesproxymodel.h or cpp?
          There are no line 29 in .h. If it goes to the cpp file it replaces line 29, goes before or after?
          I tried to add it before and after

           if(!index.isValid()) return false;
          

          in cpp. Tried to place it before and after line 29 and actually replaced line 29 but still images were not displayed.

          VRoninV 1 Reply Last reply
          0
          • G gabor53

            @VRonin
            Is

            if(role == Qt::EditRole) return QIdentityProxyModel::setData(index, value, role);
            

            goes into extrarolesproxymodel.h or cpp?
            There are no line 29 in .h. If it goes to the cpp file it replaces line 29, goes before or after?
            I tried to add it before and after

             if(!index.isValid()) return false;
            

            in cpp. Tried to place it before and after line 29 and actually replaced line 29 but still images were not displayed.

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

            @gabor53 said in QStiledItemDelegate setModelData doesn't display image:

            goes into extrarolesproxymodel.h or cpp?

            The link I posted is header only so I don't know what you are referring to. Use the line numbering you see in pastebin to understand where to put it

            "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

            G 1 Reply Last reply
            0
            • VRoninV VRonin

              @gabor53 said in QStiledItemDelegate setModelData doesn't display image:

              goes into extrarolesproxymodel.h or cpp?

              The link I posted is header only so I don't know what you are referring to. Use the line numbering you see in pastebin to understand where to put it

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

              @VRonin
              extraroleproxymodel.h looks like this:

              
              #include <QIdentityProxyModel>
              #include <QVariant>
              #include <QHash>
              class ExtraRolesProxyModel : public QIdentityProxyModel {
                Q_OBJECT
                Q_DISABLE_COPY(ExtraRolesProxyModel)
               public:
                ExtraRolesProxyModel(QObject* parent = Q_NULLPTR)
                  : QIdentityProxyModel(parent) {
              
                }
                virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE {
                  if(!index.isValid()) return QIdentityProxyModel::data(index, role);
                  const QHash<int, QHash<int, QHash<int, QVariant> > >::const_iterator rowIter = m_extraData.constFind(index.row());
                  if(rowIter == m_extraData.cend())
                    return QIdentityProxyModel::data(index, role);
                  const QHash<int, QHash<int, QVariant> >::const_iterator colIter = rowIter->constFind(index.column());
                  if(colIter == rowIter->cend())
                    return QIdentityProxyModel::data(index, role);
                  const QHash<int, QVariant>::const_iterator roleIter = colIter->constFind(role);
                  if(roleIter == colIter->cend())
                    return QIdentityProxyModel::data(index, role);
                  return roleIter.value();
                }
                virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole)Q_DECL_OVERRIDE{
                  if(!index.isValid()) return false;
                  if(role == Qt::EditRole) return QIdentityProxyModel::setData(index, value, role);
                  if(index.parent().isValid()) return QIdentityProxyModel::setData(index, value, role);
                  QHash<int, QHash<int, QHash<int, QVariant> > >::iterator rowIter = m_extraData.find(index.row());
                  if(rowIter == m_extraData.end()) {
                    if(value.isNull()) return false;
                    rowIter = m_extraData.insert(index.row(), QHash<int, QHash<int, QVariant> >());
                  }
                  QHash<int, QHash<int, QVariant> >::iterator colIter = rowIter->find(index.column());
                  if(colIter == rowIter->end()) {
                    if(value.isNull()) return false;
                    colIter = rowIter->insert(index.column(), QHash<int, QVariant>());
                  }
                  QHash<int, QVariant>::iterator roleIter = colIter->find(role);
                  if(roleIter == colIter->end()) {
                    if(value.isNull()) return false;
                    roleIter = colIter->insert(role, value);
                    return true;
                  }
                  if(value.isNull()) {
                    colIter->erase(roleIter);
                    if(colIter->isEmpty()) {
                      rowIter->erase(colIter);
                      if(rowIter->isEmpty()) {
                        m_extraData.erase(rowIter);
                      }
                    }
                    return true;
                  }
                  roleIter.value() = value;
                  return true;
                }
               private:
                QHash<int, QHash<int, QHash<int, QVariant> > > m_extraData;
              };
              
              

              It gives the following errors:
              C:\Programming\Projects\Folkfriends_bzr\checkout\extrarolesproxymodel.cpp:5: error: redefinition of 'QVariant ExtraRolesProxyModel::data(const QModelIndex&, int) const'
              QVariant ExtraRolesProxyModel::data(const QModelIndex& index, int role) const {
              ^
              C:\Programming\Projects\Folkfriends_bzr\checkout\extrarolesproxymodel.cpp:21: error: redefinition of 'bool ExtraRolesProxyModel::setData(const QModelIndex&, const QVariant&, int)'
              bool ExtraRolesProxyModel::setData(const QModelIndex& index, const QVariant& value, int role) {
              ^
              Am I still doing something incorrectly?
              Thank you.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #20

                Like the error suggests: you have the functions implemented twice. Once in the header and once in the .cpp file.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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

                  either properly split declarations and definitions between .h and .cpp or just leave everything in the .h file and delete extrarolesproxymodel.cpp altogether. The compilation process takes a bit longer but your compiler should be smart enough to avoid any difference in performance from one to the other in release mode

                  "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

                  G 2 Replies Last reply
                  0
                  • VRoninV VRonin

                    either properly split declarations and definitions between .h and .cpp or just leave everything in the .h file and delete extrarolesproxymodel.cpp altogether. The compilation process takes a bit longer but your compiler should be smart enough to avoid any difference in performance from one to the other in release mode

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

                    @VRonin
                    Now I'm just using the code in the .h file and there is no error.

                    I have the

                     if(role == Qt::EditRole) return QIdentityProxyModel::setData(index, value, role);
                    

                    line after

                    if(!index.isValid()) return false;
                    

                    (that is line 29) and I pushed the original line 29 one line down. Was that the correct way?
                    At this point no error message, but no image displayed either. Do I need to link the proxy to fixdb.cpp or fixviewdelegate .cpp?

                    1 Reply Last reply
                    0
                    • VRoninV VRonin

                      either properly split declarations and definitions between .h and .cpp or just leave everything in the .h file and delete extrarolesproxymodel.cpp altogether. The compilation process takes a bit longer but your compiler should be smart enough to avoid any difference in performance from one to the other in release mode

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

                      @VRonin
                      How can I connect the proxy to my oriinal model or fixdb?

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

                        http://doc.qt.io/qt-5/qabstractproxymodel.html#setSourceModel

                        "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

                        G 1 Reply Last reply
                        2
                        • VRoninV VRonin

                          http://doc.qt.io/qt-5/qabstractproxymodel.html#setSourceModel

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

                          @VRonin
                          Is this supposed to go in the ExtraRolesProxyModel?

                          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 Extensions
                          • Unsolved