📄 pieview.cpp
字号:
/******************************************************************************** Copyright (C) 2004-2006 Trolltech ASA. All rights reserved.**** This file is part of the example classes of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <math.h>#include <QtGui>#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;}void PieView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight){ QAbstractItemView::dataChanged(topLeft, bottomRight); validItems = 0; totalValue = 0.0; for (int row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex index = model()->index(row, 1, rootIndex()); double value = model()->data(index).toDouble(); if (value > 0.0) { totalValue += value; validItems++; } } viewport()->update();}bool PieView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event){ if (index.column() == 0) return QAbstractItemView::edit(index, trigger, event); else return false;}/* Returns the item that covers the coordinate given in the view.*/QModelIndex PieView::indexAt(const QPoint &point) const{ if (validItems == 0) return QModelIndex(); // Transform the view coordinates into contents widget coordinates. int wx = point.x() + horizontalScrollBar()->value(); int wy = point.y() + verticalScrollBar()->value(); if (wx < totalSize) { double cx = wx - totalSize/2; double cy = totalSize/2 - wy; // positive cy for items above the center // Determine the distance from the center point of the pie chart. double d = pow(pow(cx, 2) + pow(cy, 2), 0.5); if (d == 0 || d > pieSize/2) return QModelIndex(); // Determine the angle of the point. double angle = (180 / M_PI) * acos(cx/d); if (cy < 0) angle = 360 - angle; // Find the relevant slice of the pie. double startAngle = 0.0; for (int row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex index = model()->index(row, 1, rootIndex()); double value = model()->data(index).toDouble(); if (value > 0.0) { double sliceAngle = 360*value/totalValue; if (angle >= startAngle && angle < (startAngle + sliceAngle)) return model()->index(row, 1, rootIndex()); startAngle += sliceAngle; } } } else { double itemHeight = QFontMetrics(viewOptions().font).height(); int listItem = int((wy - margin) / itemHeight); int validRow = 0; for (int row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex index = model()->index(row, 1, rootIndex()); if (model()->data(index).toDouble() > 0.0) { if (listItem == validRow) return model()->index(row, 0, rootIndex()); // Update the list index that corresponds to the next valid row. validRow++; } } } return QModelIndex();}bool PieView::isIndexHidden(const QModelIndex & /*index*/) const{ return false;}/* Returns the rectangle of the item at position \a index in the model. The rectangle is in contents coordinates.*/QRect PieView::itemRect(const QModelIndex &index) const{ if (!index.isValid()) return QRect(); // Check whether the index's row is in the list of rows represented // by slices. QModelIndex valueIndex; if (index.column() != 1) valueIndex = model()->index(index.row(), 1, rootIndex()); else valueIndex = index; if (model()->data(valueIndex).toDouble() > 0.0) { int listItem = 0; for (int row = index.row()-1; row >= 0; --row) { if (model()->data(model()->index(row, 1, rootIndex())).toDouble() > 0.0) listItem++; } double itemHeight; switch (index.column()) { case 0: itemHeight = QFontMetrics(viewOptions().font).height(); return QRect(totalSize, int(margin + listItem*itemHeight), totalSize - margin, int(itemHeight)); case 1: return viewport()->rect(); } } return QRect();}QRegion PieView::itemRegion(const QModelIndex &index) const{ if (!index.isValid()) return QRegion(); if (index.column() != 1) return itemRect(index); if (model()->data(index).toDouble() <= 0.0) return QRegion(); double startAngle = 0.0; for (int row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex sliceIndex = model()->index(row, 1, rootIndex()); double value = model()->data(sliceIndex).toDouble(); if (value > 0.0) { double angle = 360*value/totalValue; if (sliceIndex == index) { QPainterPath slicePath; slicePath.moveTo(totalSize/2, totalSize/2); slicePath.arcTo(margin, margin, margin+pieSize, margin+pieSize, startAngle, angle); slicePath.closeSubpath(); return QRegion(slicePath.toFillPolygon().toPolygon()); } startAngle += angle; } } return QRegion();}int PieView::horizontalOffset() const{ return horizontalScrollBar()->value();}void PieView::mouseReleaseEvent(QMouseEvent *event){ QAbstractItemView::mouseReleaseEvent(event); selectionRect = QRect(); 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -