效果图:
主要代码:
实现放大镜效果
QPainter painter;
//两种方式
if (1) {
m_lens_image = QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);
m_lens_image.fill(0);
painter.begin(&m_lens_image);
} else {
m_lens_pixmap = QPixmap(bounds.size());
m_lens_pixmap.fill(Qt::transparent);
painter.begin(&m_lens_pixmap); //将pixmap 当做绘图设备
}
//使用渐变的方式画圆
QRadialGradient gr(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
gr.setColorAt(0.0, QColor(255, 255, 255, 191));
gr.setColorAt(0.2, QColor(255, 255, 240, 191));
gr.setColorAt(0.9, QColor(150, 150, 200, 63));
gr.setColorAt(0.95, QColor(0, 0, 0, 127));
gr.setColorAt(1, QColor(0, 0, 0, 0));
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setBrush(gr);
painter.setPen(Qt::NoPen);
painter.drawEllipse(0, 0, bounds.width(), bounds.height());
//初始化文字路径
QFontMetrics fm(f);
m_paths.clear(); //路径 QVector<QPainterPath>
m_pathBounds = QRect(); //整串文字大小边框
QPointF advance(0, 0); //文字起始点
bool do_quick = true;
for (int i=0; i<text.size(); ++i) {
if (text.at(i).unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
do_quick = false;
break;
}
}
if (do_quick) {
for (int i=0; i<text.size(); ++i) {
QPainterPath path;
path.addText(advance, f, text.mid(i, 1)); //添加文字路径
m_pathBounds |= path.boundingRect();
m_paths << path;
advance += QPointF(fm.horizontalAdvance(text.mid(i, 1)), 0);
}
} else {
QPainterPath path;
path.addText(advance, f, text);
m_pathBounds |= path.boundingRect();
m_paths << path;
}
//放大镜内的文字变形
QPainterPath MainWindow::lensDeform(const QPainterPath &source, const QPointF &offset)
{
QPainterPath path;
path.addPath(source); //传进来的就是m_paths[i]
qreal flip = 100 / qreal(100);
for (int i=0; i<path.elementCount(); ++i) {
const QPainterPath::Element &e = path.elementAt(i);
qreal x = e.x + offset.x();
qreal y = e.y + offset.y();
qreal dx = x - m_pos.x();
qreal dy = y - m_pos.y();
qreal len = m_radius - qSqrt(dx * dx + dy * dy);
//判断在不在圆内,在则修改路径各个点的位置
if (len > 0) {
path.setElementPositionAt(i,
x + flip * dx * len / m_radius,
y + flip * dy * len / m_radius);
} else {
path.setElementPositionAt(i, x, y);
}
}
return path;
}
绘图更新:
可以只更新 特定区域 ;如 update(rectBefore | rectAfter); //参数是两个矩形
paintEvent(QPaintEvent *e) 中 可以使用 e->rect(); 获取到要刷新的区域