Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to change selected row height in QListView



  • Hello,
    I created a custom QStyledItemDelegate for QListView. When I click (select) a row of listview, I want to set row height to (eg. double etc. ).

    When I debug it. sizeHint of opt.state & QStyle::State_Selected is never reached. How Can I solve it?
    Thanks

    class ListViewDelegate : public QStyledItemDelegate
    {
    public:
        void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    		QStyleOptionViewItemV4 opt = option;
    		initStyleOption(&opt, index);
    
    		QString str1 = index.model()->data(index.model()->index(index.row(), 1)).toString();
    
    		if (opt.state & QStyle::State_Selected) {
    		   painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
    		}
    	 
    		painter->setPen(Qt::black);
    		painter->drawText(opt.rect,opt.displayAlignment, str1);
        
    	}
    
    	QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const {
    		QSize result = QStyledItemDelegate::sizeHint(option, index);
    		
    QStyleOptionViewItemV4 opt = option;
    		initStyleOption(&opt, index);
    
    		if (opt.state & QStyle::State_Selected) 
    			result.setHeight(result.height()*3);
    		else
    			result.setHeight(result.height()*1);
    			
    		return result;
    	}
    };
    
    


  • @Binary-Soft
    Excuse me if this is wrong/obvious, I don't do C++ regularly. But have you (presumably in your .h file?) ensured you have marked your QSize sizeHint() declaration with the override keyword, else it will be a distinct method with the same name but not actually overriding?


  • Qt Champions 2017

    Can you confirm whether sizeHint method is called ? This will be first step. Your function signature looks right.



  • @JonB said in How to change selected row height in QListView:

    keyword
    Now I change some code. row height is changed when selected. But selected row is overlapped to next row. I think layout is not adjust for selected row.

    Thanks.

    .h

    #ifndef ListViewDelegate _H
    #define listviewdelegate _H
    
    #include <QStyledItemDelegate>
    #include <QWidget>
    #include <QPainter>
    
    #include <QDebug>
    #include <QMouseEvent>
     
    
    class ListViewDelegate  : public QStyledItemDelegate
    {
    
        Q_OBJECT
    public:
        ListViewDelegate (QWidget *parent = 0): QStyledItemDelegate(parent){
           intSelID=-1;
        }
    
        void paint(QPainter *painter, const QStyleOptionViewItem &option,
                   const QModelIndex &index) const Q_DECL_OVERRIDE;
        QSize sizeHint(const QStyleOptionViewItem &option,
                       const QModelIndex &index) const Q_DECL_OVERRIDE;
    
        bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
    
    private:
        int intSelID;
    
    
    
    };
    
    #endif // ListViewDelegate _H
    
    
    #include "listviewdelegate.h"
    
    void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(!index.isValid()) return;
    
        QStyleOptionViewItemV4 opt = option;
    
        QString str1 = index.model()->data(index.model()->index(index.row(), 1)).toString();
    
        QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
    
        QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
        if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
            cg = QPalette::Inactive;
    
        painter->setPen(Qt::black);
    
        painter->drawText(opt.rect, opt.displayAlignment,  str1);
        painter->setPen(Qt::yellow);
    
    }
    
    QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(!index.isValid())  return QSize();
        QSize result = QStyledItemDelegate::sizeHint(option, index);
    
        if (intSelID == index.row()) {
            result.setHeight(result.height()*2);
            qDebug() << " select row";
        }
        else {
            result.setHeight(result.height()*1);
            qDebug() << " de select";
        }
        return result;
    }
    
    bool ListViewDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        if (event->type() == QEvent::MouseButtonPress)
        {
            if(intSelID==index.row())
                intSelID= -1;
            else
                intSelID = index.row();
    
            ListViewDelegate::sizeHint(option,index);
        }
        return QStyledItemDelegate::editorEvent(event, model, option, index);
    }
    
    
    


  • @dheerendra
    Thanks.
    I use debug, sizeHind is work. Now row height is change but layout's height is not change.


  • Qt Champions 2017

    which layout is not changing ?



  • @dheerendra !

    Please see two pictures (before select and after select)
    I change selected row Item's height *1.8. Item's height is changed but it overlapped on next item.

    [alt text](1_1543984748851_2.png 0_1543984748850_1.jpg image url)



  • @Binary-Soft
    I already set listview's setUniformItemSizes to false.
    ui->listView->setUniformItemSizes(false);


Log in to reply