Подключил Delegate к tableView и текст вывода пропал

Есть у меня проблема с переносом текста в ячейке, если не влезает в ширину столбца. Попытался исправить добавив Delegate. Что сделал:

model = new QSqlTableModel(this,db);
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->setTable("TableEventBalancer");
model->select();

TableViewColumnDelegate *tableviewcolumnDelegate;
tableviewcolumnDelegate = new TableViewColumnDelegate;
ui->tableView->setItemDelegate(tableviewcolumnDelegate);
ui->tableView->setModel(model);
ui->tableView->setWordWrap(true);
ui->tableView->setTextElideMode(Qt::ElideNone);
int id = QFontDatabase::addApplicationFont("/usr/share/fonts/dejavu/DejaVuSansMono.ttf");
QFont font = QFont(QFontDatabase::applicationFontFamilies(id).first());
font.setPointSize(12);
ui->tableView->setFont(font);
ui->tableView->resizeColumnToContents(0);
ui->tableView->resizeColumnToContents(1);
ui->tableView->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
ui->tableView->horizontalHeader()->setResizeMode(1, QHeaderView::Fixed);
ui->tableView->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
ui->tableView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
model->setHeaderData(model->fieldIndex("number"), Qt::Horizontal, QString::fromLocal8Bit("ID"));
model->setHeaderData(model->fieldIndex("_date"), Qt::Horizontal, QString::fromLocal8Bit("Дата"));
model->setHeaderData(model->fieldIndex("text"), Qt::Horizontal, QString::fromLocal8Bit("Событие"));

Класс:

class TableViewColumnDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    enum datarole { HeaderRole = Qt::UserRole + 100, SubheaderRole};
    explicit TableViewColumnDelegate(QObject *parent = 0);
    void paint (QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QSize iconSize;
    int padding;
signals:
public slots:
};

    void TableViewColumnDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(!index.isValid())
           return;

       painter->save();
       if (option.state & QStyle::State_Selected)
           painter->fillRect(option.rect, option.palette.highlight());
       QString headerText = index.data(HeaderRole).toString();
       QString subheaderText = index.data(SubheaderRole).toString();
       QFont headerFont = QApplication::font();
       headerFont.setBold(true);
       QFont subheaderFont = QApplication::font();
       QFontMetrics headerFm(headerFont);
       QFontMetrics subheaderFm(subheaderFont);
       QRect headerRect =
               headerFm.boundingRect(option.rect.left() + iconSize.width(), option.rect.top() + padding,
                                     option.rect.width() - iconSize.width(), 0,
                                     Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
                                     headerText);
       QRect subheaderRect =
               subheaderFm.boundingRect(headerRect.left(), headerRect.bottom()+padding,
                                        option.rect.width() - iconSize.width(), 0,
                                        Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
                                        subheaderText);
       painter->setPen(Qt::black);
       painter->setFont(headerFont);
       painter->drawText(headerRect, Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap, headerText);
       painter->setFont(subheaderFont);
       painter->drawText(subheaderRect, Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap, subheaderText);
       painter->restore();
}

QSize TableViewColumnDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(!index.isValid())
        return QSize();

    QString headerText = index.data(HeaderRole).toString();
    QString subheaderText = index.data(SubheaderRole).toString();
    QFont headerFont = QApplication::font();
    headerFont.setBold(true);
    QFont subheaderFont = QApplication::font();
    QFontMetrics headerFm(headerFont);
    QFontMetrics subheaderFm(subheaderFont);

    QRect headerRect = headerFm.boundingRect(0, 0,
                                             option.rect.width() - iconSize.width(), 0,
                                             Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
                                             headerText);
    QRect subheaderRect = subheaderFm.boundingRect(0, 0,
                                                   option.rect.width() - iconSize.width(), 0,
                                                   Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
                                                   subheaderText);

    QSize size(option.rect.width(), headerRect.height() + subheaderRect.height() +  3*padding);

    if(size.height()<iconSize.height())
        size.setHeight(iconSize.height());

    return size;
}

Ответы (1 шт):

Автор решения: Roman Ozhegov

Я думаю, что это все-таки частичная реализация. Проблема данной реализации заключается в том, что необходимо ручками расставлять переносы, т.е. после редактирования нужно будет правильно расставить переносы строк. Что можно сделать перекрытием метода Delegate::setModelData. вообще я не совсем правильно сделал перекрытие делегата. По правильному нужно еще перекрыть методы setEditorData, UpdateEditorGeometry и setModelData. Было лень. Моего ответа достаточно, чтобы направить Вас в нужное русло.

CustomDelegate.h

#ifndef CUSTOMDELEGATE_H
#define CUSTOMDELEGATE_H

#include <QObject>
#include <QItemDelegate>

class CustomDelegate: public QItemDelegate
{
public:
    explicit CustomDelegate(QObject *parent = nullptr);

    // QItemDelegate interface
protected:
    virtual void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const override;

    // QAbstractItemDelegate interface
public:
    virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};

#endif // CUSTOMDELEGATE_H

CustomDelegate.cpp

#include "customdelegate.h"
#include <QPainter>
#include <QPlainTextEdit>

CustomDelegate::CustomDelegate(QObject *parent)
    : QItemDelegate(parent)
{

}

void CustomDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const
{
    painter->drawText(rect, Qt::AlignLeft, text);
}

QWidget *CustomDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    auto * edit = new QPlainTextEdit(parent);
    edit->setPlainText(index.data(Qt::DisplayRole).toString());
    return edit;
}

Использование в Widget

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    auto * model = new QStandardItemModel(2, 2);
    for (int row = 0; row < 2; ++row){
        for (int col = 0; col < 2; ++col){
            QStandardItem * item = new QStandardItem(QString("row = %1\r\ncolumn = %2").arg(row).arg(col));
            model->setItem(row, col, item);
        }
    }
    ui->tableView->setModel(model);
    auto * delegate = new CustomDelegate(this);
    ui->tableView->setItemDelegate(delegate);
}

Результат по запуску:

введите сюда описание изображения

В процессе редактирования:

введите сюда описание изображения

По окончанию редактирования:

введите сюда описание изображения

→ Ссылка