c++ - 如何更改 QProgressBar 的状态?

标签 c++ windows qt qt4 qt5

我有一个模仿和修饰的自定义对话框 QProgressDialog一些额外的特定于应用程序的信息,并启用暂停/恢复在后台运行的工作线程。最终我要寻找的是改变 QProgressBar 外观的能力。以反射(reflect)暂停状态,如 this question 中所述.

pause progress

奇怪的是QWinTaskbarProgress从 Qt 5.2 开始似乎支持这个确切的功能,但是一个普通的 QProgressBar不会,在 Qt4 或 Qt5 中。我可以在 Qt 源代码中摆弄,但我已经在 Qt 源代码中挖掘,我无法弄清楚表单控件的实际状态是在哪里查询/提供的,所以我无法弄清楚找出我需要改变的地方。也许它不存在,因为这完全是 Windows 的事情,但也许不是?

使用 CSS 覆盖样式表 as recommended in the docs (和 here )导致一个非常难看的进度条,在外观上与普通的 Windows 7 进度条完全不同。

正常:

normal appearance

样式表:

stylesheet appearance

我不想使用这个选项。

最佳答案

简单的方法是设置QGraphicsColorizeEffect到进度条。

像这样:

QProgressBar* progress = new QProgressBar;
progress->setGraphicsEffect(new QGraphicsColorizeEffect);

Win7 上的结果:

enter image description here

嗯...结果看起来不错,但我们可以让它变得更好,只改变 block 的颜色。

最终结果如下:

enter image description here

重新实现 QGraphicsEffect::draw 以指定和自定义着色效果区域:

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 .

顺便说一句,转介 Qt source code

关于c++ - 如何更改 QProgressBar 的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49867207/

相关文章:

c++ - 将 QString/QByteArray 转换为科学记数法 qt

c++ - 将 vector 传递给 C++ 中的函数时出现类型问题

c++ - 在多态对象上使用 typeid 时,必须定义它吗?

Visual Studio 2013 中的 C++11 计时

c++ - 如何在 c++ (visual studio) 中使用 julia 语言

c++ - 将事件/ Action 连接到 QPlainTextEdit

c++ - 平台工具集 v140 和 v140_xp 有什么区别?

windows - 以编程方式更改任务栏设置?

c# - 如何检索可执行文件的相对路径

c++ - 如何在 QT 中使用 DEBUG 对齐日志文件中的数据?