QTableView and Image



  • I'm drawing images in QTableView by QItemDelegate class.
    now the problem here is , the part of the image , that could fit in the block is only being displayed.

    Another thing is , is it possible to create something like, whenever a block from QTableView is selected ,the image on that particular block should get changed?



  • can you show us your current code?



  • Here's the widget class

    MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    {
            QTableView *view=new QTableView(this);
            view->setShowGrid(false);
            view->setFocus();
            QStandardItemModel *model=new QStandardItemModel(3,2);
            myDelegate *delegate=new myDelegate;
    
            
            view->columnWidth(500);// no matter what I put in here, it remains of the same size
            view->rowHeight(500); //same as mentioned above, I tried to take the height and width
              //of the image for column width and column height but nothing happened.
    
            view->setModel(model);
            view->setItemDelegate(delegate);
            QStringList SL={"Column 1","Column 2"};
            model->setHorizontalHeaderLabels(SL);
            QStandardItem *item=new QStandardItem;
            model->setItem(0,0,item);
    }
           
    

    And the QItemDelegate class, paint method

    void myDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
        const QStandardItemModel *model=static_cast<const QStandardItemModel*>(index.model());
    
         painter->drawImage(option.rect.x(),option.rect.y(),m_image);
    
    }
    


  • @MokJ said in QTableView and Image:

        view->columnWidth(500);// no matter what I put in here, it remains of the same size
        view->rowHeight(500); //same as mentioned above, I tried to take the height and width
          //of the image for column width and column height but nothing happened.
    

    I'm not saying this is the right way to do it, but these lines do nothing. Look carefully at the documentation: columnWidth/rowHeight are getters, you want the setters here! In general, Qt uses methods named set... for every property you can set.



  • @JonB thanks , I've got it, that problem has just been solved.
    Now I'm trying to display a new image to that particular block by selecting it ,is there a way ? I mean the point is ....the rest of the Table must not get affected .

    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) ;
    

    can it be used or should I go for

    void updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem &option,const QModelIndex &index)const;
    


    • Where does m_image come from?
    • Are you subclassing QItemDelegate or QStyledItemDelegate?
    • Are you implementing myDelegate::sizeHint?

    LEAKFEST!

    The view does not own either the model or the delegate. You need to pass a parent to them or they are leaked



  • thank you @VRonin , It was a mistake of mine ,that I didn't provide the complete information.
    I'm subclassing QItemDelegate....on this note how its different from subclassing QStyledItemDelegate?? I mean Qt document says that

    QStyledItemDelegate uses the current style to paint its items

    whats the current style here !!

    QSize myDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{
              return  QSize newSize(70,30);
    }
    
    QImage m_image(":/new/prefix1/d.jpg");
    

    m_image is in private of myDelegate.



  • So m_image does not depend at all on what's in the model?

    @MokJ said in QTableView and Image:

    whats the current style here !!

    http://doc.qt.io/qt-5/style-reference.html

    Let's go step by step. The below should be an improvement already, correct?

    void myDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
    (option.widget ? option.widget.style() : QApplication::style())->drawItemPixmap(painter,option.rect(),QPixmap::fromImage(m_image.scaled(option.rect().size())));
    }
    


  • @VRonin Thanks
    yes, m_image doesn't depend on model at all.
    I'm clear about current style now.

    Let's go step by step. The below should be an improvement already, correct?

    yes , after a small change It has improved.
    So whats the next step !
    What method should be used to get desired output !

    @MokJ said in QTableView and Image:

    Another thing is , is it possible to create something like, whenever a block from QTableView is selected ,the image on that particular block should get changed?



  • @MokJ said in QTableView and Image:

    So whats the next step !

    We make the image depend on the model.
    In the constructor add:

    connect(view->selectionModel(),&QItemSelectionModel::selectionChanged,[view](const QItemSelection &selected, const QItemSelection &deselected)->void{
    QModelIndexList indexList = selected.indexes();
    for(auto& index : qAsConst(indexList))
    view->model()->setData(index,true,Qt::UserRole);
    indexList = deselected.indexes();
    for(auto& index : qAsConst(indexList))
    view->model()->setData(index,QVariant(),Qt::UserRole);
    });
    

    now in myDelegate::paint you can add if(index.data(Qt::UserRole).toBool()) to check if an item is selected or not



  • @VRonin Thank you
    I have added that snippet too, now question is , How is it making m_image depend on model ?



  • @MokJ I made a mistake, if(index.data().toBool()) should have been if(index.data(Qt::UserRole).toBool()) fixed above now

    P.S.
    if(index.data(Qt::UserRole).isValid()) does the same and it's probably more efficient



  • @VRonin
    I'm a bit confused about how its supposed to work. I mean once I select an Index it goes inside

    if(index.data(Qt::UserRole).isValid()) {}
    

    What should get implemented in If?

    I appreciate your help greatly.



  • @VRonin
    can we take the Image as string ?



  • @VRonin
    I got it,
    in If , I'm drawing the new Image.
    Thanks very much @VRonin.
    Now If we want to keep that image in model should we implement

    void setModelData(QWidget*editor,QAbstractItemModel *model,const QModelIndex &index)const
    

    again thanks @VRonin .



  • @hjohn
    I came across this , maybe it could be helpful.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.