Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QAbstractTableModel subclass with hyperlink

QAbstractTableModel subclass with hyperlink

Scheduled Pinned Locked Moved General and Desktop
3 Posts 2 Posters 3.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    misker
    wrote on last edited by
    #1

    Does anybody know of an existing subclass of QAbstractTableModel and/or its delegate, which is designed to allow rich text in the table cells (for hyperlinks)? Preferably also with sorting that works as expected (on the text shown and not on the url of the hyperlink). Just wanted to see if I can save myself the trouble of writing it if something like this already existed.

    Thanks.

    1 Reply Last reply
    0
    • jazzycamelJ Offline
      jazzycamelJ Offline
      jazzycamel
      wrote on last edited by
      #2

      I've actually done this quite literally for a column of hyperlinks that open in the default web browser when clicked. It doesn't actually need any extra functionality in the model, just a delegate and a proxy model. The following is a fully working example:

      main.cpp
      @
      #include <QtCore>
      #include <QtGui>

      #include <tablemodel.h>
      #include <richtextdelegate.h>
      #include <richtextproxy.h>

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

      RichTextDelegate delegate;
      
      TableModel model;
      
      RichTextProxy proxy;
      proxy.setSourceModel(&model);
      
      QTableView view;
      view.setModel(&proxy);
      delegate.setTableView(&view);
      view.setItemDelegate(&delegate);
      view.setSortingEnabled(true);
      view.show();
      
      return a.exec&#40;&#41;;
      

      }
      @

      tablemodel.h
      @
      #ifndef TABLEMODEL_H
      #define TABLEMODEL_H

      #include <QAbstractTableModel>
      #include <QVariant>

      class TableModel : public QAbstractTableModel
      {
      Q_OBJECT
      public:
      explicit TableModel(QObject *parent = 0);
      int rowCount(const QModelIndex &parent) const;
      int columnCount(const QModelIndex &parent) const;
      QVariant data(const QModelIndex &index, int role) const;
      };

      #endif // TABLEMODEL_H
      @

      tablemodel.cpp
      @
      #include "tablemodel.h"

      TableModel::TableModel(QObject *parent) :
      QAbstractTableModel(parent)
      {
      }

      int TableModel::rowCount(const QModelIndex &parent) const {
      Q_UNUSED(parent);
      return 10;
      }

      int TableModel::columnCount(const QModelIndex &parent) const {
      Q_UNUSED(parent);
      return 10;
      }

      QVariant TableModel::data(const QModelIndex &index, int role) const {
      if(!index.isValid() || role!=Qt::DisplayRole) return QVariant();

      return QString("<a href='http://some.url/?row=%1&col=%2'>(%1,%2)</a>").arg(index.row()).arg(index.column());
      

      }
      @

      richtextdelegate.h
      @
      #ifndef RICHTEXTDELEGATE_H
      #define RICHTEXTDELEGATE_H

      #include <QItemDelegate>
      #include <QTableView>

      class RichTextDelegate : public QItemDelegate
      {
      Q_OBJECT
      public:
      explicit RichTextDelegate(QObject *parent = 0);
      void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
      void setTableView(QTableView *view){ this->view=view; }

      private:
      QTableView *view;
      };

      #endif // RICHTEXTDELEGATE_H
      @

      richtextdelegate.cpp
      @
      #include "richtextdelegate.h"

      #include <QLabel>

      RichTextDelegate::RichTextDelegate(QObject *parent) :
      QItemDelegate(parent)
      {}

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

      if(view->indexWidget(index)!=0) return;
      
      QLabel *label=new QLabel;
      label->setTextFormat(Qt::RichText);
      label->setTextInteractionFlags(Qt::TextBrowserInteraction);
      label->setOpenExternalLinks(true);
      label->setText(index.data().toString());
      view->setIndexWidget(index, label);
      

      }
      @

      richtextproxy.h
      @
      #ifndef RICHTEXTPROXY_H
      #define RICHTEXTPROXY_H

      #include <QSortFilterProxyModel>

      class RichTextProxy : public QSortFilterProxyModel
      {
      Q_OBJECT
      public:
      explicit RichTextProxy(QObject *parent = 0);

      protected:
      bool lessThan(const QModelIndex &left, const QModelIndex &right) const;

      };

      #endif // RICHTEXTPROXY_H
      @

      richtextproxy.cpp
      @
      #include "richtextproxy.h"
      #include <QTextDocument>

      RichTextProxy::RichTextProxy(QObject *parent) :
      QSortFilterProxyModel(parent)
      {}

      bool RichTextProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {

      QTextDocument doc;
      
      doc.setHtml(left.data().toString());
      QString leftText=doc.toPlainText();
      
      doc.setHtml(right.data().toString());
      QString rightText=doc.toPlainText();
      
      return leftText<rightText;
      

      }
      @

      Sorry for the crazy long post ;o) Basically the delegate just sets a QLabel for each cell (via the paint function) which acts as the rich text renderer. The proxy model uses QTextDocument to convert the rich text data to plain text (i.e. strip the markup) and then do the less than comparison. Hope this helps ;o)

      For the avoidance of doubt:

      1. All my code samples (C++ or Python) are tested before posting
      2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
      1 Reply Last reply
      0
      • M Offline
        M Offline
        misker
        wrote on last edited by
        #3

        Well that's fantastic! Including sort too. It's much appreciated.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved