【问题标题】:Progress bar with differnet text color around the progress front?进度条周围有不同文本颜色的进度条?
【发布时间】:2012-12-01 09:33:16
【问题描述】:

如何从 Qt 中为 QProgressBar 中的文本获得以下效果? :

我的想法是我必须在进度条的左侧部分有一个更亮的颜色。

【问题讨论】:

  • 进度条的外观很大程度上取决于 Widget 样式,这是一个用户设置(主题)。如果你想做自己的效果,你需要自己实现进度条。这很容易。
  • 我考虑过重叠两个文本图层并将蒙版与其中一个文本图层链接,该文本图层的尺寸与填充区域相同。这就是你的想法?
  • 我没有关注你。什么意思?
  • 当您接受答案并对之前的问题投赞成票时,您会在问题上获得更多帮助。
  • 好吧,我并不是说你应该为我的每一句话都亲自+1。

标签: qt text colors qt5 qprogressbar


【解决方案1】:

我会按如下方式进行自定义绘图:

  1. 从 QLabel 派生您自己的进度条类。

  2. 覆盖paintEvent()函数。

  3. 在paintEvent()中,使用QPainter开始绘制:

你最终应该得到你想要达到的目标。由于 Qt 的默认双缓冲,您应该不会观察到闪烁。

【讨论】:

    【解决方案2】:

    this的帮助下,

    QModernProgressBar.h

    #include <QWidget>
    #include <QProgressBar>
    #include <QPaintEvent>
    #include <QStylePainter>
    #include <QStyleOption>
    #include <QDebug>
    
    class QModernProgressBar : public QProgressBar 
    {
        Q_OBJECT
       public:
        explicit QModernProgressBar(QWidget *parent = nullptr);
        ~QModernProgressBar() Q_DECL_OVERRIDE;
    
       protected:
        void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
    
    public:
        virtual QString text() const Q_DECL_OVERRIDE;
    };
    

    QModernProgressBar.cpp

    #include "QModernProgressBar.h"
    
    QModernProgressBar::QModernProgressBar(QWidget *parent) : QProgressBar(parent) {}
    
    QModernProgressBar::~QModernProgressBar() {}
    
    /* https://www.qtcentre.org/threads/70885-QProgressBar-with-in-decimal */
    
    QString QModernProgressBar::text() const
    {
        QString result = format();
        if(minimum() ==0 && maximum()==0)
        {
            if(result=="%p%")
            {
                return QString("");
            }
            else
            {
                return result;
            }
        }
        else if ( minimum() == maximum() ) 
        {
            return QString("");
        }
    
        if(result.isEmpty())
        {
            return QString("%p%");
        }
        else
        {
            return result;
        }
    }
    
    void QModernProgressBar::paintEvent(QPaintEvent *ev)
    {
        Q_UNUSED(ev)
        QStylePainter paint(this);
        QStyleOptionProgressBar opt;
        initStyleOption(&opt);
    
        paint.drawControl(QStyle::CE_ProgressBarGroove, opt);
        paint.drawControl(QStyle::CE_ProgressBarContents, opt);
    
        const QStyleOptionProgressBar *option = &opt;
        QStylePainter *painter = &paint;
    
        // Stolen from QFusionStyle::drawControl
        if (const QStyleOptionProgressBar *pbar = qstyleoption_cast<const QStyleOptionProgressBar *>(option))
        {
            QRect leftRect;
            QRect rect = pbar->rect;
            QColor textColor            = option->palette.text().color();
            QColor alternateTextColor   = option->palette.window().color();
    
            painter->save();
            bool vertical = false, inverted = false;
            vertical = (pbar->orientation == Qt::Vertical);
            inverted = pbar->invertedAppearance;
            if (vertical)
                rect = QRect(rect.left(), rect.top(), rect.height(), rect.width());
            const auto totalSteps = qMax(Q_INT64_C(1), qint64(pbar->maximum) - pbar->minimum);
            const auto progressSteps = qint64(pbar->progress) - pbar->minimum;
            const int progressIndicatorPos = static_cast<int>(progressSteps * rect.width() / totalSteps);
            if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
                leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
            if (vertical)
                leftRect.translate(rect.width() - progressIndicatorPos, 0);
    
            bool flip = (!vertical && (((pbar->direction == Qt::RightToLeft) && !inverted) ||
                        ((pbar->direction == Qt::LeftToRight) && inverted)));
    
            QString formattedText = pbar->text;
            formattedText.replace(QLatin1String("%m"), QString("%1").arg(totalSteps));
            const auto progress = static_cast<int>((qint64(value()) - pbar->minimum) * 100.0 / totalSteps);
            formattedText.replace(QLatin1String("%p"), QString("%1").arg(progress));
            QRegion rightRect = rect;
            rightRect = rightRect.subtracted(leftRect);
            painter->setClipRegion(rightRect);
            painter->setPen(flip ? alternateTextColor : textColor);
            painter->drawText(rect, formattedText, QTextOption(Qt::AlignAbsolute |
                                                               Qt::AlignHCenter  |
                                                               Qt::AlignVCenter));
            if (!leftRect.isNull())
            {
    
                painter->setPen(flip ? textColor : alternateTextColor);
                painter->setClipRect(leftRect);
                painter->drawText(rect, formattedText, QTextOption(Qt::AlignAbsolute |
                                                                   Qt::AlignHCenter  |
                                                                   Qt::AlignVCenter));
            }
            painter->restore();
        }
    }
    

    main.cpp

    #include <QApplication>
    #include <QTimer>
    #include <QTextStream>
    #include <QTimer>
    #include <QDebug>
    #include <QVBoxLayout>
    #include "QModernProgressBar.h"
    
    int main(int argc, char* argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QCoreApplication::setApplicationName("QModernProgressbar Demo");
        QApplication app(argc, argv);
        app.setStyleSheet(QLatin1String("                                   \
            QProgressBar {                                                  \
                font-family                 : Fira Code;                    \
                font-size                   : 12pt;                         \
                font-style                  : normal;                       \
                font-weight                 : bold;                         \
                color           : rgba(8, 218, 157, 100%);                  \
                border          : 1px solid rgba(8, 218, 157, 100%);        \
                border-radius       : 0px;                                  \
                text-align          : center;                               \
            }                                                               \
                                                                            \
            QProgressBar::chunk {                                           \
                background-color    : rgba(8, 218, 157, 100%);              \
                width               : 1px;                                  \
                text-align          : center;                               \
            }"));                                                           \
    
        QTimer timer;
        QWidget mainWindow;
        InvertProgressBar w1, w2, w3;
    
        w1.setTextVisible(true);
        w2.setTextVisible(true);
        w3.setTextVisible(true);
        int i=25;
        int j=0;
    
        w1.setRange(0,25);
        w2.setRange(0,100);
        w3.setRange(0,0);
    
        w1.setFormat(QString("Searching... Timing out in %1 seconds.").arg(i));
        w2.setFormat(QString("Flashing the controller ..."));
        w3.setFormat(QString("Rebooting the controller ..."));
        QVBoxLayout *finalLayout = new QVBoxLayout;
    
        QObject::connect(&timer, &QTimer::timeout, [&]() {
                                                            w1.setFormat(QString("Searching... Timing out in %1 seconds...").arg(i));
                                                            w1.setValue(i);
                                                            if(--i==-1)
                                                            {
                                                                i=25;
                                                            }
                                                            w2.setFormat(QString("Flashing the controller ...%p%"));
                                                            w2.setValue(j);
                                                            if(j++==101)
                                                            {
                                                                j=0;
                                                            }
                                                          }
                                                          );
        timer.start(500);
        finalLayout->addWidget(&w1);
        finalLayout->addWidget(&w2);
        finalLayout->addWidget(&w3);
        mainWindow.setFixedSize(500,150);
        mainWindow.setLayout(finalLayout);
        mainWindow.show();
        return app.exec();
    }
    

    请注意,当忙指示灯亮时,双音文本无效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-19
      • 2017-01-12
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      相关资源
      最近更新 更多