Vladimir Bershov
Vladimir Bershov

Reputation: 2832

QListView set Custom Editor via QStyledItemDelegate::createEditor

I want to show custom widget in each QListView cells (3 labels width different fonts and 2 tool buttons). The widget must handle mouse events for correct handling of the hover events and button clicks. (Therefore I cannot just draw it in QStyledItemDelegate::paint()).

Here is what I want each row in a list view looks like:
enter image description here

The main idea: QAbstractItemView::openPersistentEditor().


#include <QApplication>

#include <QWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
#include <QVBoxLayout>

#include <QDateTime>

#include <QListView>
#include <QStringListModel>
#include <QStyledItemDelegate>

class Form : public QWidget
{
    //Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr)
        :QWidget(parent)
    {
        verticalLayout = new QVBoxLayout(this);
        horizontalLayout = new QHBoxLayout();

        labelTitle = new QLabel(this);
        labelTitle->setFont(QFont("Calibri", 12, QFont::Bold));
        horizontalLayout->addWidget(labelTitle);

        toolButtonEdit = new QToolButton(this);
        toolButtonEdit->setText("E");
        horizontalLayout->addWidget(toolButtonEdit);

        toolButtonRemove = new QToolButton(this);
        toolButtonRemove->setText("R");
        horizontalLayout->addWidget(toolButtonRemove);

        verticalLayout->addLayout(horizontalLayout);

        labelDate = new QLabel(this);
        labelDate->setFont(QFont("Calibri", 8));
        verticalLayout->addWidget(labelDate);

        labelText = new QLabel(this);
        labelText->setFont(QFont("Calibri", 10));
        verticalLayout->addWidget(labelText);

        verticalLayout->setStretch(2, 1);

        setMinimumSize(QSize(300, 50));
    }

public:
    QVBoxLayout *verticalLayout;
    QHBoxLayout *horizontalLayout;
    QLabel *labelTitle;
    QToolButton *toolButtonEdit;
    QToolButton *toolButtonRemove;
    QLabel *labelDate;
    QLabel *labelText;
};


class MyDelegate : public QStyledItemDelegate
{
public:
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
    {
        auto editor = new Form(parent);
        return editor;
    }

    void setEditorData(QWidget *ed, const QModelIndex &index) const override
    {
        QVariant var = index.model()->data(index, Qt::DisplayRole);

        if (Form *editor = dynamic_cast<Form*>(ed))
        {
            editor->labelTitle->setText("SYMBOL");
            editor->labelDate->setText("date-time");
            editor->labelText->setText(var.toString());
        }
    }
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex &)const override
    {
        editor->setGeometry(option.rect);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Form form(nullptr);
    form.labelTitle->setText("TITLE");
    form.labelDate->setText(QDateTime::currentDateTime().toString());
    form.labelText->setText("text body");
    form.show();

    auto model = new QStringListModel;
    model->setStringList(QStringList()
        << "text body 1"
        << "text body 2"
        << "text body 3");

    auto view = new QListView(nullptr);
    view->setModel(model);
    view->setItemDelegate(new MyDelegate);

    int rowCount = model->rowCount();
    for (int row = 0; row < rowCount; ++row)
    {
        QModelIndex index = model->index(row, 0);
        view->openPersistentEditor(index);
    }

    view->show();

    return a.exec();
}

Here is how the list view actually looks:
enter image description here


What how can one set such a custom widget to show view cells?

Upvotes: 0

Views: 603

Answers (1)

SebDieBln
SebDieBln

Reputation: 3469

Note that while you are defining your own delegate MyDelegate you never actually use it (i.e. by calling QAbstractItemView::setItemDelegate(). Therefore you see the default delegate (a simple QLineEdit for data of type QString) when calling openPersistentEditor().

Upvotes: 1

Related Questions