Dzień dobry. W głównym oknie swojego programu dodałem QListWidget. Następnie utworzyłem klasę, która dziedziczy po QWidget. Za pomocą osobnego okna dialogowego tworzyłem nowe obiekty i dodawałem je do QListWidget. Wszystko było w porządku aż do momentu, w którym zorientowałem się, że przy próbie zmiany kolejności elementów w QListWidget zawartość poszczególnych elementów jest usuwana. Poszperałem w Internecie i znalazłem informację, że w celu utworzenia listy widgetów, które będę chciał w pewnym stopniu edytować (zmieniać kolejność) najlepiej użyć QListView + Model/View + Delegate. I w tym momencie zaczynają się schody.

Sprawdziłem ten przykład: https://doc.qt.io/qt-6/qtwidgets-itemviews-stardelegate-example.html

Niestety za dużo z niego nie zrozumiałem. Utworzyłem swój własny (roboczy) model oraz delegate,ale nadal nie wiem w jaki sposób mogę narysować swój widget. Poniżej model oraz delegate:

operationwidgetmodel.h

#ifndef OPERATIONWIDGETMODEL_H
#define OPERATIONWIDGETMODEL_H

#include <QAbstractItemModel>

class OperationWidgetModel : public QAbstractItemModel
{
    Q_OBJECT
public:
   explicit OperationWidgetModel(QObject *parent = nullptr);

    QVariant data(const QModelIndex &index, int role) const override;
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &index) const override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

};

#endif // OPERATIONWIDGETMODEL_H

operationwidgetmodel.cpp

#include "operationwidgetmodel.h"

OperationWidgetModel::OperationWidgetModel(QObject *parent) : QAbstractItemModel(parent)
{
    //
}

QVariant OperationWidgetModel::data(const QModelIndex &index, int role) const
{
    return QVariant();
}


QModelIndex OperationWidgetModel::index(int row, int column, const QModelIndex &parent) const
{
    QModelIndex index;

    index = createIndex(row,column,nullptr);
    return index;
}

QModelIndex OperationWidgetModel::parent(const QModelIndex &index) const
{
    return QModelIndex();
}

int OperationWidgetModel::rowCount(const QModelIndex &parent) const
{
    if(parent.isValid())return 0;

    return 1;
}

int OperationWidgetModel::columnCount(const QModelIndex &parent) const
{
    if(parent.isValid()) return 0;
    return 1;
}

operationwidgetdelegate.h

#ifndef OPERATIONWIDGETDELEGATE_H
#define OPERATIONWIDGETDELEGATE_H

#include <QStyledItemDelegate>
#include "operationwidget.h"

class OperationWidgetDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    OperationWidgetDelegate(QObject *parent = nullptr);

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const override;
    QSize sizeHint(const QStyleOptionViewItem &option,
                   const QModelIndex &index) const override;
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;
    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;


};

#endif // OPERATIONWIDGETDELEGATE_H

operationwidgetdelegate.cpp

#include "operationwidgetdelegate.h"



OperationWidgetDelegate::OperationWidgetDelegate(QObject *parent)
{

}

void OperationWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{

    QStyledItemDelegate::paint(painter,option,index);
}

QSize OperationWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{

    OperationWidget widget;

    return QSize(widget.geometry().width(),widget.geometry().height());
}

QWidget *OperationWidgetDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    OperationWidget *widget = new OperationWidget(parent);

    return widget;
}

void OperationWidgetDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    OperationWidget *widget = qobject_cast<OperationWidget*>(editor);
    if(widget)
    {
        widget->SetOperationName("Cięcie");
    }

}

void OperationWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    OperationWidget *widget = qobject_cast<OperationWidget*>(editor);

    if(widget)
    {
        model->setData(index,widget->GetOperationName(),Qt::EditRole);
    }
}

Do czasu gdy używałem QListWidget, dodawałem nowe obiekty OperationWidget za pomocą sygnału, który przekazywał wybrane przez użytkownika parametry i ustawiał je w widgecie:

screenshot-20230117221257.png

Po przejściu na QListView nie bardzo wiem jak to wszystko ustawić. O ile operationwidgetmodel wydaje mi się ustawiony dobrze (wygląda tak jak chciałem), o tyle sam delegate już niezbyt. Brakuje mi rysowania widgetu, ładowania podanych danych, zmiany pozycji w liście i reszty funkcji, które miałem już zrobione w QListWidget. Będę wdzięczny za jakiekolwiek wskazówki jak poradzić sobie z "dodawaniem" własnego widgetu do QListView za pomocą modelu i delegate. Poniżej jeszcze zrzut z QListWidget na to jak całość wyglądała przed zmianą na QListView.

screenshot-20230117221812.png

Pozdrawiam serdecznie :]