Search code examples
qtuser-interfacesymbianqlistwidgetqitemdelegate

How to create Symbian style list views in Qt


I've never done any item delegates in Qt before, and I think the documentation doesn't explain well about more complex delegates.

I need to create 2 styles of Symbian(^3) style lists

Type 1:

Delegate style 1

This is for common navigation lists, the icon and the lower label are optional.

Type 2:

Delegate style 2

This is for settings lists, where the pushbutton can be a toggle(on/off)-button or execute a context menu, etc.

How would I go on creating these sort of item delegates?

Best Regards, Rat


Solution

  • I had to make something similar once. This is how I did it.

    My delegate class declaration. As you can see it has a member: QLabel *label. You can add another label or a pushbutton, depending on your needs.

    class MyItemDelegate : public QStyledItemDelegate
    {
    public:
        explicit MyItemDelegate(QObject *parent = 0);
        ~MyItemDelegate();
    protected:
        void paint(QPainter *painter,
                   const QStyleOptionViewItem &option, const QModelIndex &index) const;
        QSize sizeHint(const QStyleOptionViewItem &option,
                       const QModelIndex &index) const;
    private:
        QLabel *label;
    };
    

    My paint() and sizeHint() methods.

    QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(!index.isValid())
            return QSize();
        QVariant data = index.data(Qt::DisplayRole);
    
        label->setText(data.toString());
        label->resize(label->sizeHint());
        QSize size(option.rect.width(), label->height());
        return size;
    }
    
    void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(!index.isValid())
            return;
        QVariant data = index.data(Qt::DisplayRole);
    
        // Not necessary to do it here, as it's been already done in sizeHint(), but anyway.
        label->setText(data.toString());
    
        painter->save();
    
        QRect rect = option.rect;
    
        // This will draw a label for you. You can draw a pushbutton the same way.
        label->render(painter, QPoint(rect.topLeft().x(), rect.center().y() - label->height() / 2),
                      QRegion(label->rect()), QWidget::RenderFlags());
    
        painter->restore();
    }
    

    Hope this is what you've been looking for. Good luck!