怎样子类化QAbstractItemView,

goodluck365168 2017-08-10 09:03:18
怎样子类化QAbstractItemView,最好给个简单例子研究下
...全文
323 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
goodluck365168 2017-08-11
  • 打赏
  • 举报
回复
还是有点复杂,不过有点启发
ronal7do 2017-08-10
  • 打赏
  • 举报
回复
摘自Qt官方例子Chart Example

#ifndef PIEVIEW_H
  #define PIEVIEW_H

  #include <QAbstractItemView>

  class PieView : public QAbstractItemView
  {
      Q_OBJECT

  public:
      PieView(QWidget *parent = 0);

      QRect visualRect(const QModelIndex &index) const override;
      void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
      QModelIndex indexAt(const QPoint &point) const override;

  protected slots:
      void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
                       const QVector<int> &roles = QVector<int>()) override;
      void rowsInserted(const QModelIndex &parent, int start, int end) override;
      void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;

  protected:
      bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) override;
      QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,
                             Qt::KeyboardModifiers modifiers) override;

      .....

  private:
      QRect itemRect(const QModelIndex &item) const;
      QRegion itemRegion(const QModelIndex &index) const;
      int rows(const QModelIndex &index = QModelIndex()) const;
      void updateGeometries() override;

      int margin;
      int totalSize;
      int pieSize;
      int validItems;
      double totalValue;
      QPoint origin;
      QRubberBand *rubberBand;
  };

  #endif // PIEVIEW_H

#include <QtWidgets>
  #include <cmath>

  #ifndef M_PI
  #define M_PI 3.1415927
  #endif

  #include "pieview.h"

  PieView::PieView(QWidget *parent)
      : QAbstractItemView(parent)
  {
      horizontalScrollBar()->setRange(0, 0);
      verticalScrollBar()->setRange(0, 0);

      margin = 8;
      totalSize = 300;
      pieSize = totalSize - 2 * margin;
      validItems = 0;
      totalValue = 0.0;
      rubberBand = 0;
  }

  int PieView::horizontalOffset() const
  {
      return horizontalScrollBar()->value();
  }

  void PieView::mousePressEvent(QMouseEvent *event)
  {
      QAbstractItemView::mousePressEvent(event);
      origin = event->pos();
      if (!rubberBand)
          rubberBand = new QRubberBand(QRubberBand::Rectangle, viewport());
      rubberBand->setGeometry(QRect(origin, QSize()));
      rubberBand->show();
  }

  void PieView::mouseMoveEvent(QMouseEvent *event)
  {
      if (rubberBand)
          rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
      QAbstractItemView::mouseMoveEvent(event);
  }

  void PieView::mouseReleaseEvent(QMouseEvent *event)
  {
      QAbstractItemView::mouseReleaseEvent(event);
      if (rubberBand)
          rubberBand->hide();
      viewport()->update();
  }

  QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction cursorAction,
                                  Qt::KeyboardModifiers /*modifiers*/)
  {
      QModelIndex current = currentIndex();

      switch (cursorAction) {
          case MoveLeft:
          case MoveUp:
              if (current.row() > 0)
                  current = model()->index(current.row() - 1, current.column(),
                                           rootIndex());
              else
                  current = model()->index(0, current.column(), rootIndex());
              break;
          case MoveRight:
          case MoveDown:
              if (current.row() < rows(current) - 1)
                  current = model()->index(current.row() + 1, current.column(),
                                           rootIndex());
              else
                  current = model()->index(rows(current) - 1, current.column(),
                                           rootIndex());
              break;
          default:
              break;
      }

      viewport()->update();
      return current;
  }

  void PieView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
  {
      for (int row = start; row <= end; ++row) {
          QModelIndex index = model()->index(row, 1, rootIndex());
          double value = model()->data(index).toDouble();
          if (value > 0.0) {
              totalValue -= value;
              --validItems;
          }
      }

      QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
  }

  void PieView::scrollContentsBy(int dx, int dy)
  {
      viewport()->scroll(dx, dy);
  }

  void PieView::scrollTo(const QModelIndex &index, ScrollHint)
  {
      QRect area = viewport()->rect();
      QRect rect = visualRect(index);

      if (rect.left() < area.left()) {
          horizontalScrollBar()->setValue(
              horizontalScrollBar()->value() + rect.left() - area.left());
      } else if (rect.right() > area.right()) {
          horizontalScrollBar()->setValue(
              horizontalScrollBar()->value() + qMin(
                  rect.right() - area.right(), rect.left() - area.left()));
      }

      if (rect.top() < area.top()) {
          verticalScrollBar()->setValue(
              verticalScrollBar()->value() + rect.top() - area.top());
      } else if (rect.bottom() > area.bottom()) {
          verticalScrollBar()->setValue(
              verticalScrollBar()->value() + qMin(
                  rect.bottom() - area.bottom(), rect.top() - area.top()));
      }

      update();
  }

  /*
      Find the indices corresponding to the extent of the selection.
  */

  void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
  {
      // Use content widget coordinates because we will use the itemRegion()
      // function to check for intersections.

      QRect contentsRect = rect.translated(
                              horizontalScrollBar()->value(),
                              verticalScrollBar()->value()).normalized();

      int rows = model()->rowCount(rootIndex());
      int columns = model()->columnCount(rootIndex());
      QModelIndexList indexes;

      for (int row = 0; row < rows; ++row) {
          for (int column = 0; column < columns; ++column) {
              QModelIndex index = model()->index(row, column, rootIndex());
              QRegion region = itemRegion(index);
              if (region.intersects(contentsRect))
                  indexes.append(index);
          }
      }

      if (indexes.size() > 0) {
          int firstRow = indexes[0].row();
          int lastRow = indexes[0].row();
          int firstColumn = indexes[0].column();
          int lastColumn = indexes[0].column();

          for (int i = 1; i < indexes.size(); ++i) {
              firstRow = qMin(firstRow, indexes[i].row());
              lastRow = qMax(lastRow, indexes[i].row());
              firstColumn = qMin(firstColumn, indexes[i].column());
              lastColumn = qMax(lastColumn, indexes[i].column());
          }

          QItemSelection selection(
              model()->index(firstRow, firstColumn, rootIndex()),
              model()->index(lastRow, lastColumn, rootIndex()));
          selectionModel()->select(selection, command);
      } else {
          QModelIndex noIndex;
          QItemSelection selection(noIndex, noIndex);
          selectionModel()->select(selection, command);
      }

      update();
  }

  void PieView::updateGeometries()
  {
      horizontalScrollBar()->setPageStep(viewport()->width());
      horizontalScrollBar()->setRange(0, qMax(0, 2*totalSize - viewport()->width()));
      verticalScrollBar()->setPageStep(viewport()->height());
      verticalScrollBar()->setRange(0, qMax(0, totalSize - viewport()->height()));
  }

  int PieView::verticalOffset() const
  {
      return verticalScrollBar()->value();
  }

  /*
      Returns the position of the item in viewport coordinates.
  */

  QRect PieView::visualRect(const QModelIndex &index) const
  {
      QRect rect = itemRect(index);
      if (!rect.isValid())
          return rect;

      return QRect(rect.left() - horizontalScrollBar()->value(),
                   rect.top() - verticalScrollBar()->value(),
                   rect.width(), rect.height());
  }

  /*
      Returns a region corresponding to the selection in viewport coordinates.
  */

  QRegion PieView::visualRegionForSelection(const QItemSelection &selection) const
  {
      int ranges = selection.count();

      if (ranges == 0)
          return QRect();

      QRegion region;
      for (int i = 0; i < ranges; ++i) {
          QItemSelectionRange range = selection.at(i);
          for (int row = range.top(); row <= range.bottom(); ++row) {
              for (int col = range.left(); col <= range.right(); ++col) {
                  QModelIndex index = model()->index(row, col, rootIndex());
                  region += visualRect(index);
              }
          }
      }
      return region;
  }
第1章 混合桌面/internet应用程序 1.1 internet相关窗口部件 1.2 webkit的使用 第2章 声音和视频 2.1 qsound和qmovie的使用 2.2 phonon多媒体框架 第3章 模型/视图表格模型 3.1 qt的模型/视图架构 3.2 用于表格的qstandarditemmodel 3.3 创建自定义表格模型 第4章 模型/视图树模型 4.1 用于树qstandarditemmodel的用法 4.2 创建自定义树模型 第5章 模型/视图委托 5.1 与数据类型相关的编辑器 5.2 与数据类型相关的委托 5.3 与模型相关的委托 第6章 模型/视图中的视图 6.1 qabstractitemview子类 .6.2 与模型相关的可视视图 第7章 用qtconcurrent实现线程处理 7.1 在线程中执行函数 7.2 线程中的过滤和映射 第8章 用qthread实现线程处理 8.1 独立项的处理 8.2 共享项的处理 第9章 创建富文本编辑器 9.1 qtextdocument简介 9.2 创建自定义的文本编辑器 9.3 一个单行的富文本编辑器 9.4 编辑多行的富文本 第10章 创建富文本文档 10.1 高质量地输出qtextdocument文件 10.2 创建qtextdocument 10.3 输出和打印文档 10.4 绘制页面 第11章 创建图形/视图窗口 11.1 图形/视图架构 11.2 图形/视图窗口部件和布局 11.3 图形项简介 第12章 创建图形/视图场景 12.1 场景、项和动作 12.2 增强qgraphicsview的功能 12.3 创建可停靠的工具箱窗口部件 12.4 创建自定义图形项 第13章 动画和状态机框架 13.1 动画框架简介 13.2 状态机框架简介 13.3 动画和状态机的结合 结束语 精选书目
作 者(英)萨默菲尔德 著,白建平 等译 出 版 社电子工业出版社 出版时间2011-4-1 ISBN9787121131103 第1章 混合桌面/Internet应用程序  1.1 Internet相关窗口部件  1.2 WebKit的使用 第2章 声音和视频  2.1 QSound和QMovie的使用  2.2 Phonon多媒体框架第3章 模型/视图表格模型  3.1 Qt的模型/视图架构  3.2 用于表格的QStandardItemModel  3.3 创建自定义表格模型 第4章 模型/视图树模型  4.1 用于树QStandardItemModel的用法  4.2 创建自定义树模型 第5章 模型/视图委托   5.1 与数据类型相关的编辑器  5.2 与数据类型相关的委托  5.3 与模型相关的委托 第6章 模型/视图中的视图  6.1 QAbstractItemView子类  6.2 与模型相关的可视视图 第7章 用QtConcurrent实现线程处理  7.1 在线程中执行函数  7.2 线程中的过滤和映射 第8章 用QThread实现线程处理  8.1 独立项的处理  8.2 共享项的处理 第9章 创建富文本编辑器  9.1 QTextDocument简介  9.2 创建自定义的文本编辑器  9.3 一个单行的富文本编辑器  9.4 编辑多行的富文本 第10章 创建富文本文档  10.1高质量地输出QTextDocument文件  10.2 创建QTextDocument  10.3 输出和打印文档  10.4 绘制页面 第11章 创建图形/视图窗口  11.1 图形/视图架构  11.2 图形/视图窗口部件和布局  11.3 图形项简介 第12章 创建图形/视图场景  12.1 场景、项和动作  12.2 增强QGraphicsView的功能  12.3 创建可停靠的工具箱窗口部件  12.4 创建自定义图形项 第13章 动画和状态机框架  13.1 动画框架简介  13.2 状态机框架简介  13.3 动画和状态机的结合 结束语 精选书目

16,199

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧