问:如何为QLabel创建清晰可见的发光效果? (例如使用QGraphicsDropShadowEffect)

时间:2015-03-07 18:08:00

标签: c++ qt graphics

我正在尝试为QLabel添加一个发光效果,使其看起来像时间显示在下图中:

enter image description here

我发现你可以“误用”QGraphicsDropShadowEffect

QGraphicsDropShadowEffect * dse = new QGraphicsDropShadowEffect();
dse->setBlurRadius(10);
dse->setOffset(0);
dse->setColor(QColor(255, 255, 255));
ui.label->setGraphicsEffect(dse);

然而,由此产生的效果太弱,你几乎看不到它:

enter image description here

不幸的是,你不能修改效果的强度,只能修改颜色和模糊半径。

一个想法是将多个QGraphicsDropShadowEffect应用于标签,以便由于重叠而更加明显。但是,调用ui.label->setGraphicsEffect(dse);将始终删除任何以前的效果,即我无法将多个QGraphicsEffect设置为同一个对象。

如何使用Qt创建清晰可见的发光效果?

1 个答案:

答案 0 :(得分:2)

与此同时,我根据QGraphicsBlurEffect并使用部分this answer修改了我自己的图形效果。如果您知道更好的解决方案,请与我们联系。

<强> qgraphicsgloweffect.h:

#pragma once
#include <QGraphicsEffect>
#include <QGraphicsBlurEffect>
#include <QGraphicsColorizeEffect>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QPainter>

class QGraphicsGlowEffect :
  public QGraphicsEffect
{
public:
  explicit QGraphicsGlowEffect(QObject *parent = 0);

  QRectF boundingRectFor(const QRectF &rect) const;
  void setColor(QColor value);
  void setStrength(int value);
  void setBlurRadius(qreal value);
  QColor color() const;
  int strength() const;
  qreal blurRadius() const;

protected:
  void draw(QPainter* painter);

private:
  static QPixmap applyEffectToPixmap(QPixmap src, QGraphicsEffect *effect, int extent);
  int _extent = 5;
  QColor _color = QColor(255, 255, 255);
  int _strength = 3;
  qreal _blurRadius = 5.0;
};

<强> qgraphicsgloweffect.cpp:

#include "QGraphicsGlowEffect.h"
#include <QtCore\qmath.h>

QGraphicsGlowEffect::QGraphicsGlowEffect(QObject *parent) : QGraphicsEffect(parent)
{
}

void QGraphicsGlowEffect::setColor(QColor value) {
  _color = value;
}

void QGraphicsGlowEffect::setStrength(int value) {
  _strength = value;
}

void QGraphicsGlowEffect::setBlurRadius(qreal value) {
  _blurRadius = value;
  _extent =  qCeil(value);
  updateBoundingRect();
}

QColor QGraphicsGlowEffect::color() const {
  return _color;
}

int QGraphicsGlowEffect::strength() const {
  return _strength;
}

qreal QGraphicsGlowEffect::blurRadius() const {
  return _blurRadius;
}

QRectF QGraphicsGlowEffect::boundingRectFor(const QRectF &rect) const {
  return QRect(
      rect.left() - _extent,
      rect.top() - _extent,
      rect.width() + 2 * _extent, 
      rect.height() + 2 * _extent);
}

void QGraphicsGlowEffect::draw(QPainter* painter) {
  QPoint offset;
  QPixmap source = sourcePixmap(Qt::LogicalCoordinates, &offset);
  QPixmap glow;

  QGraphicsColorizeEffect *colorize = new QGraphicsColorizeEffect;
  colorize->setColor(_color);
  colorize->setStrength(1);
  glow = applyEffectToPixmap(source, colorize, 0);

  QGraphicsBlurEffect *blur = new QGraphicsBlurEffect;
  blur->setBlurRadius(_blurRadius);
  glow = applyEffectToPixmap(glow, blur, _extent);

  for (int i = 0; i < _strength; i++)
    painter->drawPixmap(offset - QPoint(_extent, _extent), glow);
  drawSource(painter);
}

QPixmap QGraphicsGlowEffect::applyEffectToPixmap(
  QPixmap src, QGraphicsEffect *effect, int extent)
{
  if (src.isNull()) return QPixmap();
  if (!effect) return src;
  QGraphicsScene scene;
  QGraphicsPixmapItem item;
  item.setPixmap(src);
  item.setGraphicsEffect(effect);
  scene.addItem(&item);
  QSize size = src.size() + QSize(extent * 2, extent * 2);
  QPixmap res(size.width(), size.height());
  res.fill(Qt::transparent);
  QPainter ptr(&res);
  scene.render(&ptr, QRectF(), QRectF(-extent, -extent, size.width(), size.height()));
  return res;
}

然后你就可以使用它:

QGraphicsGlowEffect * glow = new QGraphicsGlowEffect();
glow->setStrength(4);
glow->setBlurRadius(7);
ui.label->setGraphicsEffect(glow);

这会产生很好的发光效果:

enter image description here