Delegate that paint entire widget area



  • Hello everybody, I want ask you help for a problem in model/view paradigm. Above there is a simple code to illustrate my issue. What I want to achieve is to paint 4 rectangles in a list view, but I cannot fill all the space that the listview widget has. It seems that option.widget->width() return the right size available to draw the rects but some space (approx 20 pixels) are reserved always for the scrollbar.

    full size
    The picture above shows that the rects are too big so the four "icons" are drawn in one column and four rows

    reduced size
    This images shows that when I subtract some pixels from the sizeHint function in mydelegate (commented code in line 26 of mydelegate.cpp) the rects fit the area, no scrollbar is created but obviously there is an ugly white vertical line in its place.

    This is the example code:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "mymodel.h"
    #include "mydelegate.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
        myModel model;
        myDelegate delegate;
    };
    
    #endif // MAINWINDOW_H
    
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->listView->setModel(&model);
        ui->listView->setItemDelegate(&delegate);
        ui->listView->setViewMode(QListView::IconMode);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    #ifndef MYMODEL_H
    #define MYMODEL_H
    
    #include <QAbstractListModel>
    #include <QColor>
    
    class myModel : public QAbstractListModel
    {
        Q_OBJECT
    
    public:
        explicit myModel(QObject *parent = nullptr);
    
        // Basic functionality:
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    
    private:
        QColor array[4];
    };
    
    #endif // MYMODEL_H
    
    
    #include "mymodel.h"
    #include <QDebug>
    
    myModel::myModel(QObject *parent)
        : QAbstractListModel(parent)
    {
        array[0] = QColor(18,226,240);
        array[1] = QColor(253,25,151);
        array[2] = QColor(211,211,211);
        array[3] = QColor(255,105,105);
    }
    
    int myModel::rowCount(const QModelIndex &parent) const
    {
        // For list models only the root node (an invalid parent) should return the list's size. For all
        // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
        if (parent.isValid())
            return 0;
    
        return 4;
    }
    
    QVariant myModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
    
        if (role == Qt::UserRole){
            int colorIndex = index.row();
                return array[colorIndex];
            }
    
        return QVariant();
    }
    
    
    #ifndef MYDELEGATE_H
    #define MYDELEGATE_H
    #include <QStyledItemDelegate>
    #include <QPainter>
    
    class myDelegate : public QStyledItemDelegate
    {
    public:
        myDelegate();
    
        void paint(QPainter *painter, const QStyleOptionViewItem &option,
                   const QModelIndex &index) const;
    
        QSize sizeHint(const QStyleOptionViewItem &option,
                       const QModelIndex &index ) const;
    };
    
    #endif // MYDELEGATE_H
    
    
    #include "mydelegate.h"
    
    
    myDelegate::myDelegate()
    {
    }
    
    void myDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        painter->save();
    
        QVariant variant = index.data(Qt::UserRole);
    
        if ( !variant.isNull() ){
            QColor color = variant.value<QColor>();
            QRect rect = QRect(option.rect);
    
            painter->fillRect(rect,color);
        }
        painter->restore();
    }
    
    QSize myDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize( /* -11 + */ option.widget->width() / 2, /* -3 + */ option.widget->height() / 2 );
    }
    
    

    Is option.widget->width() and option.widget->height() the right way to fill the entire widget area?
    Thank you all for any tips and support.

    Edit:
    Project zip file. (Link valid until 09/21/17)


  • Qt Champions 2016

    Hi
    the images are not visible.


  • Qt Champions 2016

    Hi
    Could you try
    setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
    setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );

    and see if it still reserve space?

    UPDATE
    it is still reserved.


  • Qt Champions 2016

    Hi
    Mr @VRonin suggested we looked at
    http://doc.qt.io/qt-5/qabstractscrollarea.html#maximumViewportSize
    so maybe yo u need to subclass view and return full area.


Log in to reply
 

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