我有一个自定义对话框,它模仿和修饰QProgressDialog一些额外的特定于应用程序的信息,并允许暂停/恢复在后台运行的工作线程。最终我正在寻找的是能够改变QProgressBar的外观以反映this question中描述的暂停状态。
奇怪的是,QWinTaskbarProgress似乎支持Qt 5.2的这个确切功能,但是在Qt4或Qt5中没有普通的QProgressBar。我可以在Qt源代码中摆弄,但是我已经在Qt源代码中挖掘了一下,我无法弄清楚查询/提供表单控件的实际状态,所以我无法弄清楚我需要改变什么。也许它不存在,因为这完全是Windows的事情,但也许不是吗?
使用CSS覆盖StyleSheet as recommended in the docs(以及here)会产生一个非常难看的进度条,与Windows 7进度条的存在完全不同。
正常:
样式表:
我不想使用此选项。
答案 0 :(得分:3)
简单的方法是将QGraphicsColorizeEffect设置为进度条。
像这样:
QProgressBar* progress = new QProgressBar;
progress->setGraphicsEffect(new QGraphicsColorizeEffect);
Win7上的结果:
嗯...结果看起来很好,但我们可以做得更好,只改变块颜色。
以下是最终结果:
重新实施QGraphicsEffect::draw
到特定&自定义colourize效果区域:
class Colorize : public QGraphicsEffect {
public:
explicit Colorize(QObject *parent = Q_NULLPTR) :
QGraphicsEffect(parent),
strength(1),
color(Qt::red),
effectRect()
{ }
quint32 strength;
QColor color;
QRectF effectRect;
protected:
void draw(QPainter* painter) {
QPoint offset;
const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset);
draw(painter, offset, pixmap, QRect());
}
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
if (src.isNull())
return;
QImage srcImage;
QImage destImage;
if (srcRect.isNull()) {
srcImage = src.toImage();
srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
destImage = QImage(srcImage.size(), srcImage.format());
} else {
QRect rect = srcRect.toAlignedRect().intersected(src.rect());
srcImage = src.copy(rect).toImage();
srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
destImage = QImage(rect.size(), srcImage.format());
}
destImage.setDevicePixelRatio(src.devicePixelRatioF());
// do colorizing
QPainter destPainter(&destImage);
grayscale(srcImage, destImage, srcImage.rect());
destPainter.setCompositionMode(QPainter::CompositionMode_Screen);
destPainter.fillRect(effectRect, color);
destPainter.end();
// alpha blending srcImage and destImage
if(0 < strength && strength < 1){
QImage buffer = srcImage;
QPainter bufPainter(&buffer);
bufPainter.setOpacity(strength);
bufPainter.drawImage(0, 0, destImage);
bufPainter.end();
destImage = buffer;
}
if (srcImage.hasAlphaChannel())
destImage.setAlphaChannel(srcImage.alphaChannel());
painter->drawImage(dest, destImage);
}
};
计算进度条的grove rect:
QRectF getGrooveRect() const {
StyleOptionProgressBar option;
option.initFrom(this); // this ⇒ progress bar
return style()->subElementRect(QStyle::SE_ProgressBarGroove, &option, this);
}
...
class StyleOptionProgressBar : public QStyleOptionProgressBar {
public:
using QStyleOptionProgressBar::QStyleOptionProgressBar;
void initFrom(const ColorizeProgressBar* w) {
init(w);
minimum = w->minimum();
maximum = w->maximum();
progress = w->value();
text = w->text();
textAlignment = w->alignment();
textVisible = w->isTextVisible();
orientation = w->orientation();
invertedAppearance = w->invertedAppearance();
}
};
Github上的完整来源。
BTW,推荐Qt source code