qtqabstractitemmodelqabstracttablemodelqabstractlistmodel

QAbstractTableModel data return html code to display


I want my AbstracttableModel subclass data() method to return html i.e.

PreText<b>Text</b>PostText

And this text must be displayed int table as in html: PreTextTextPostText

How can I do this?


Solution

  • You can create a delegate for the view that will display the html.

    class HtmlDelegate : public QItemDelegate {
    public:
        HtmlDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
    
        // This function is only called to paint the text
        void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
                         const QRect &rect, const QString &text) const
        {
            QTextDocument doc;
    
            // Since the QTextDocument will do all the rendering, the color,
            // and the font have to be put back inside the doc
            QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
                                      ? QPalette::Normal : QPalette::Disabled;
            if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
                cg = QPalette::Inactive;
            QColor textColor = option.palette.color(cg, QPalette::Text);
            doc.setDefaultStyleSheet(QString("body { color: %1}")
                                     .arg(textColor.name()));
            doc.setDefaultFont(option.font);
            doc.setHtml(text);
            doc.setDocumentMargin(1); // the default is 4 which is too much
    
            painter->save();
            painter->translate(rect.topLeft());
            doc.drawContents(painter);
            painter->restore();
        }
    
        // bold and underlined characters take more space
        // so you have to redefine this function as well
        // (if you have a checkbox or an icon in the item, you will have
        // to include their size to the returned value)
        QSize sizeHint(const QStyleOptionViewItem &option,
                       const QModelIndex &index) const
        {
            QTextDocument doc;
            doc.setDefaultFont(option.font);
            doc.setHtml(index.data(Qt::DisplayRole).toString());
            doc.setDocumentMargin(1);
            return doc.size().toSize();
        }
    };
    

    Then assign it to a view:

    view->setItemDelegateForColumn(0, new HtmlDelegate(view));