c ++ - Hvordan ændrer jeg tilstanden til en QProgressBar?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en brugerdefineret dialog, der efterligner og pryder QProgressDialog med nogle yderligere applikationsspecifikke oplysninger og muliggør pausering/genoptagelse af arbejdstrådens tråd i baggrunden. I sidste ende er det, jeg leder efter, evnen til at ændre udseendet af QProgressBar for at afspejle pausetilstanden som beskrevet i dette spørgsmål. [5] [6]


pause progress [8]


Mærkeligt nok synes QWinTaskbarProgress at understøtte denne nøjagtige funktionalitet som fra Qt 5.2, men en ren QProgressBar ikke, i Qt4 eller Qt5. Jeg er okay med at svinge rundt i Qt-kildekoden, men jeg har gravet rundt i Qt-kildekoden, og jeg kan ikke finde ud af, hvor den egentlige tilstand af formularstyringen er forespurgt, så jeg kan ikke regne ud hvad jeg skal ændre. Måske er det ikke der fordi dette er strengt en Windows ting, men måske ikke? [9] [10]


Brug CSS til at tilsidesætte StyleSheet som anbefalet i docs (og her) resulterer i en meget grim progresslinje, helt anderledes end udseende fra Windows 7 Progress Bar. [11]


Normal:


normal udseende [13]


stylesheet:


stylesheet udseende [14]


Jeg vil ikke bruge denne mulighed.

Bedste reference


Den enkle måde er at indstille QGraphicsColorizeEffect til statuslinjen. [15]


Sådan her:


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


Resultat på Win7:


Indtast billedbeskrivelse her [16]


Umm ... resultatet ser ud som fint, men vi kan gøre det bedre, kun ændre klumpfarven.


Her er det endelige resultat:


Indtast billedbeskrivelse her [17]


Reimplement QGraphicsEffect::draw til specifik & Tilpas farveområdeområdet:


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);
    }
}; 


Beregner rillens rektangulære på fremdriftslinjen:


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();
    }
};


Komplet kilde på Github. [18]


BTW, henvist Qt kildekode [19]