带超链接的Tableview

#ifndef URLVIEW_H
#define URLVIEW_H

#include <QWidget>
#include <QTableView>


class UrlView : public QTableView
{
    Q_OBJECT
public:
    explicit UrlView(QWidget *parent = nullptr);

protected:
    void mousePressEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

    QString anchorAt(const QPoint &pos) const;
signals:
    void linkActivated(QString link);
    void linkHovered(QString link);
    void linkUnhovered();
};

#endif // URLVIEW_H
#include "urlview.h"
#include <QStandardItemModel>

#include <QAbstractTextDocumentLayout>
#include <QHeaderView>
#include <QPainter>
#include <QScrollBar>
#include <QStyledItemDelegate>
#include <QTextDocument>
#include <QLabel>
#include <QTextBlock>

struct Date {
  QString msg;
  QString url;
  QString urlTip;
};

QVector<Date> datas = {
    {"this is %1 , is a very inter warfldjeo welrk3eo wsfm3ekih",
     "https://www.runoob.com/", "cainiao"},
    {"If you want to provide your users with an editable rich text editor, use "
     "%1. If you want a text browser without hypertext navigation use",
     "https://doc.qt.io/qt-5/qtextedit.html", "QTextEdit"},
    {"this is %1 , is a very inter warfldjeo welrk3eo wsfm3ekih",
     "https://www.runoob.com/", "cainiao"}};

class LinkableItemDelegate : public QStyledItemDelegate {

public:
  explicit LinkableItemDelegate(QObject *parent = 0) {}

  QString anchorAt(const QString& html,const QPoint &point) const {
    QTextDocument doc;
    doc.setTextWidth(360);
    doc.setHtml(html);

    auto textLayout = doc.documentLayout();
    Q_ASSERT(textLayout != 0);
    QPointF p = point - textPoint_;

    return textLayout->anchorAt(p);
  }

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

    painter->save();
    QRect rect = option.rect;
    painter->fillRect(QRect(rect.x() + 50, rect.y(), 300, 380),
                      QColor("#ff8833"));

    QString text = datas[index.column()].msg;
    text = text.arg(QString("<a href=\"%1\">%2</a>")
                        .arg(datas[index.column()].url)
                        .arg(datas[index.column()].urlTip));
   QString html_ =
        QString("<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head> \
                           <body>\
                            <p style=\"color:rgb(255,0,0)\"> <font color=\"#00ff00\">%1.  </font>                 \
                            %2  \
                            </p>                \
                            </body></html>")
            .arg(index.column() + 1)
            .arg(text);
    QRect textRect(rect.x() + 20, rect.y() + 400, 360, 100);

    QTextDocument doc;
    doc.setHtml(html_);
    doc.setTextWidth(textRect.width());
    textPoint_ = QPointF(20, 400);
    painter->translate(textRect.x(), textRect.y());
    doc.drawContents(painter);
    //    painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop |
    //    Qt::TextWordWrap,
    //                      html);
    painter->restore();
  }
  QSize sizeHint(const QStyleOptionViewItem &option,
                 const QModelIndex &index) const override {
    return QSize(400, 500);
  }

private:
  mutable QPointF textPoint_;
};

class LinkTableViewModel : public QAbstractTableModel {

public:
  LinkTableViewModel(QObject *parent = 0) {}

  int rowCount(const QModelIndex &parent) const override { return 1; }
  int columnCount(const QModelIndex &parent) const override {
    return datas.size();
  }
  QVariant data(const QModelIndex &index, int role) const override {

      if(role == Qt::DisplayRole){
          QString text = datas[index.column()].msg;
          text = text.arg(QString("<a href=\"%1\">%2</a>")
                              .arg(datas[index.column()].url)
                              .arg(datas[index.column()].urlTip));
          QString html =
              QString("<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head> \
                          <body>\
                          <p style=\"color:rgb(255,0,0)\"> <font color=\"#00ff00\">%1.  </font>                 \
                       %2  \
                         </p>                \
                         </body></html>")
                             .arg(index.column() + 1)
                             .arg(text);
          return html;
      }
      return QVariant();
  }
  QVariant headerData(int section, Qt::Orientation orientation,
                      int role) const override {
      if(role == Qt::DisplayRole){
          return "aaa";
      }
      return QVariant();
  }


  Qt::ItemFlags flags(const QModelIndex &index) const override {
    return QAbstractTableModel::flags(index);
  }
};

UrlView::UrlView(QWidget *parent) : QTableView{parent} {
  setMouseTracking(true);

  setModel(new LinkTableViewModel(this));
  setItemDelegate(new LinkableItemDelegate(this));
  setShowGrid(false);
  this->horizontalHeader()->setVisible(false);
  this->verticalHeader()->setVisible(false);
  setSelectionMode(QTableView::NoSelection);
  resizeColumnsToContents();
  resizeRowsToContents();
}

void UrlView::mousePressEvent(QMouseEvent *event) {
    QString linkStr = anchorAt(event->pos());
    if(linkStr.size() > 1){
        emit linkActivated(linkStr);
    }
}

void UrlView::mouseReleaseEvent(QMouseEvent *event) {}

void UrlView::mouseMoveEvent(QMouseEvent *event) {

    if(anchorAt(event->pos()).size() > 1){
        setCursor(Qt::OpenHandCursor);
    }
    else
    {
        setCursor(Qt::ArrowCursor);
    }
}

QString UrlView::anchorAt(const QPoint &pos) const {

  auto index = indexAt(pos);
  if (index.isValid()) {
    auto delegate = this->itemDelegateForIndex(index);
    auto linkableDelegate = dynamic_cast<LinkableItemDelegate *>(delegate);
    if (linkableDelegate != 0) {
      auto itemRect = visualRect(index);
      auto relativeClickPosition = pos - itemRect.topLeft();
      QString html = model()->data(index, Qt::DisplayRole).toString();
      return linkableDelegate->anchorAt(html,relativeClickPosition);
    }
  }
  return "";
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值