pieview.cpp

来自「Qt开发的GRE背单词软件」· C++ 代码 · 共 175 行

CPP
175
字号
#define _USE_MATH_DEFINES
#include <cmath>
#include <QScrollBar>
#include <QFontMetrics>
#include <QPainter>
#include <QPaintEvent>
#include "PieView.h"

PieView::PieView(QWidget *parent) : QAbstractItemView(parent) {}

double PieView::getValue(int row) const {
	return model()->data(model()->index(row, AMOUNT)).toDouble();
}

int PieView::getValidItems()
{
	int result = 0;
	for(int row = 0; row < model()->rowCount(); ++row)
		if(getValue(row) > 0.0)
			result++;
	return result;
}

double PieView::getTotalAmount() const
{
	double result= 0.0;
	for(int row=0; row<model()->rowCount(); ++row)
		result += getValue(row);
	return result;
}

void PieView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	validItems = getValidItems();
	QAbstractItemView::dataChanged(topLeft, bottomRight);
}

QString PieView::getText(int row)
{
	return tr("%1 %2(%3)").arg(model()->data(model()->index(row, NAME)).toString())
						  .arg(getValue(row))
						  .arg(model()->data(model()->index(row, PERCENTAGE)).toString());
}

double PieView::getDeltaAngle(int row) {
	return 360 * getValue(row) / getTotalAmount();
}

QColor PieView::getColor(int row) {
	return QColor(
		model()->data(model()->index(row, NAME), Qt::DecorationRole).toString());
}

void PieView::drawText(QPainter& painter, double startAngle, 
					   double deltaAngle, const QString& text)
{
	if(deltaAngle > 0)
	{
		int width = QFontMetrics(painter.font()).width(text);
		int r = pieSize / 3;
		int x = r*cos((startAngle+deltaAngle/2)*M_PI/180);
		int y = r*sin((startAngle+deltaAngle/2)*M_PI/180);
		painter.drawText(pieSize/2 + x - width/2, pieSize/2 - y, text);
	}
}

void PieView::drawPie(QPainter& painter, double startAngle, 
					  double deltaAngle, const QColor& color)
{
	if(deltaAngle > 0)
	{
		painter.setBrush(color);
		painter.drawPie(0, 0, pieSize, pieSize, startAngle*16, deltaAngle*16);
	}
}

void PieView::drawPies(QPainter& painter)
{
	double startAngle = 0.0;
	for(int row = 0; row < model()->rowCount(); ++row)
	{
		drawPie(painter, startAngle, getDeltaAngle(row), getColor(row));
		startAngle += getDeltaAngle(row);
	}
}

void PieView::drawTexts(QPainter& painter)
{
	double startAngle = 0.0;
	for(int row = 0; row < model()->rowCount(); ++row)
	{
		drawText(painter, startAngle, getDeltaAngle(row), getText(row));
		startAngle += getDeltaAngle(row);
	}
}

void PieView::paintEvent(QPaintEvent *event)
{
	QPainter painter(viewport());
	painter.setRenderHint(QPainter::Antialiasing);
	painter.fillRect(event->rect(), viewOptions().palette.base());
	painter.setPen(viewOptions().palette.color(QPalette::Foreground));

	if (validItems > 0)
	{
		if(viewport()->width() > viewport()->height())
			painter.translate((viewport()->width() - pieSize)/2, margin);
		else
			painter.translate(margin, (viewport()->height() - pieSize)/2);
		painter.drawEllipse(0, 0, pieSize, pieSize);
		drawPies (painter);
		drawTexts(painter);
	}
}

void PieView::resizeEvent(QResizeEvent*)
{
	int totalSize = qMin(viewport()->width(), viewport()->height());
	pieSize = totalSize - 2*margin;
}


// inherited
QModelIndex PieView::indexAt(const QPoint&) const {
    return QModelIndex();
}

bool PieView::isIndexHidden(const QModelIndex&) const {
    return false;
}

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

QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers)
{
    viewport()->update();
    return currentIndex();
}

void PieView::scrollTo(const QModelIndex&, ScrollHint) {
    update();
}

void PieView::setSelection(const QRect&, QItemSelectionModel::SelectionFlags) {
    update();
}

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

QRegion PieView::visualRegionForSelection(const QItemSelection&) const {
	return QRegion();
}

QRect PieView::visualRect(const QModelIndex&) const {
	return QRect(0, 0, pieSize, pieSize);
}

void PieView::setModel(QAbstractItemModel *m) {
	if (model()) {
		disconnect(model(), SIGNAL(rowsRemoved(const QModelIndex&,int,int)), viewport(), SLOT(update()));
		disconnect(model(), SIGNAL(rowsInserted(const QModelIndex&,int,int)), viewport(), SLOT(update()));
		disconnect(model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex &)), viewport(), SLOT(update()));
	}
	QAbstractItemView::setModel(m);
	if (model()) {
		connect(model(), SIGNAL(rowsRemoved(const QModelIndex&,int,int)), viewport(), SLOT(update()));
		connect(model(), SIGNAL(rowsInserted(const QModelIndex&,int,int)), viewport(), SLOT(update()));
		connect(model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), viewport(), SLOT(update()));
	}
	dataChanged(QModelIndex(), QModelIndex()); // generate the pie for the first time
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?