/
waterstone
/
TaskList_Demo
Обзор
Документация
Войти
/
waterstone
/
TaskList_Demo
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
QPixmapCache
src/tasklist_progress_cell_delegate.cpp
177 строк
5 KB
Peter Sakhno
Try QPixmapCache in TaskListProgressCellDelegate::paint
22 янв 2026, 11:43
22 янв 2026, 11:43
3d0c513
Код
Авторство
О чём код?
#include "tasklist_progress_cell_delegate.h" #include <QPainter> #include <QPixmapCache> #include <QGuiApplication> #include "tasklist_ranges.h" namespace { #if 0 static const QString kPixmapKeyTemplate{ "TaskListProgressCellDelegate,%1,%2,%3,%4,%5,%6,%7" }; #else static const QString kPixmapKeyTemplate{ "TaskListProgressCellDelegate_%1_%2_%3_%4_%5_%6_%7" }; #endif // 0 QRectF squared(const QRectF& rect) { if (rect.width() > rect.height()) { qreal diff = rect.width() - rect.height(); return rect.adjusted(diff / 2, 0, -diff / 2, 0); } else { qreal diff = rect.height() - rect.width(); return rect.adjusted(0, diff / 2, 0, -diff / 2); } } } QSize TaskListProgressCellDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { auto hint = QStyledItemDelegate::sizeHint(option, index); if (hint.width() < kMinSize.width()) hint.setWidth(kMinSize.width()); if (hint.height() < kMinSize.height()) hint.setHeight(kMinSize.height()); return hint; } void TaskListProgressCellDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyledItemDelegate::paint(painter, option, index); const auto var = index.data(Qt::UserRole); if (var.userType() != QMetaType::Int) return; int progress = var.toInt(); if (!ProgressRange::valid(progress) and !AnimationRange::valid(progress)) return; auto bounds = squared(option.rect.adjusted(kPenWidth, kPenWidth, -kPenWidth, -kPenWidth)); #if 0 bounds.moveCenter(option.rect.center()); #endif // 0 QPalette::ColorGroup group = QPalette::Inactive; QPalette::ColorRole role = QPalette::Text; int back_alpha = 20; static const int fore_alpha = 255; if (option.state & QStyle::State_Active and option.state & QStyle::State_Selected) { group = QPalette::Active; role = QPalette::HighlightedText; back_alpha = 50; } QColor color = QGuiApplication::palette().color(group, role); QString back_key = kPixmapKeyTemplate. arg("back"). arg(0). arg(kPenWidth). arg(back_alpha). arg(color.rgb()). arg(bounds.width()). arg(bounds.height()); QPixmap back_pixmap; if (!QPixmapCache::find(back_key, &back_pixmap)) { auto generate_pixmap = [&]() -> QPixmap { QPixmap pixmap = QPixmap{ bounds.size().toSize() }; pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing, true); color.setAlpha(back_alpha); painter.setPen(QPen(color, kPenWidth, Qt::SolidLine, Qt::FlatCap)); painter.drawArc( { {kPenWidth/2.0, kPenWidth/2.0}, bounds.size() - QSize{kPenWidth, kPenWidth} }, 0, 360 * 16); return pixmap; }; back_pixmap = generate_pixmap(); QPixmapCache::insert(back_key, back_pixmap); } // Draw pixmap at center of item painter->drawPixmap(bounds.toRect(), back_pixmap); QString fore_key = kPixmapKeyTemplate. arg("fore"). arg(progress). arg(kPenWidth). arg(fore_alpha). arg(color.rgb()). arg(bounds.width()). arg(bounds.height()); QPixmap fore_pixmap; if (!QPixmapCache::find(fore_key, &fore_pixmap)) { auto generate_pixmap = [&]() -> QPixmap { QPixmap pixmap = QPixmap{ bounds.size().toSize() }; pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing, true); const QRectF rc{ {kPenWidth / 2.0, kPenWidth / 2.0}, bounds.size() - QSize{kPenWidth, kPenWidth} }; color.setAlpha(fore_alpha); painter.setPen(QPen(color, kPenWidth, Qt::SolidLine, Qt::FlatCap)); if (ProgressRange::valid(progress)) { painter.drawArc(rc, 90 * 16, -((progress * 360 / ProgressRange::max()) * 16 + 90)); } else if (AnimationRange::valid(progress)) { painter.drawArc(rc, -(progress - AnimationRange::min() - 90) * 16, -45 * 16); } return pixmap; }; fore_pixmap = generate_pixmap(); QPixmapCache::insert(fore_key, fore_pixmap); } // Draw pixmap at center of item painter->drawPixmap(bounds.toRect(), fore_pixmap); #if 0 painter->setRenderHint(QPainter::Antialiasing); color.setAlpha(back_alpha); painter->setPen(QPen(color, kPenWidth, Qt::SolidLine, Qt::FlatCap)); painter->drawArc(bounds, 0, 360 * 16); color.setAlpha(fore_alpha); painter->setPen(QPen(color, kPenWidth, Qt::SolidLine, Qt::FlatCap)); if (ProgressRange::valid(progress)) { painter->drawArc(bounds, 90 * 16, -((progress * 360 / ProgressRange::max()) * 16 + 90)); } else if (AnimationRange::valid(progress)) { painter->drawArc(bounds, -(progress - AnimationRange::min() - 90) * 16, -45 * 16); } #endif // 0 }