Пользовательский круговой индикатор выполнения в Qt

Я могу сделать круговой индикатор выполнения в qt, переопределяя paintEvent виджета и рисуя круговой индикатор выполнения, но испытывая трудности со вторым круговым индикатором выполнения (не могу рисовать так) за основным круговым индикатором выполнения:

введите здесь описание изображения

Может ли кто-нибудь провести меня? Заранее спасибо.


person elgolondrino    schedule 14.03.2017    source источник
comment
что такое второй круговой прогрессбар?   -  person eyllanesc    schedule 14.03.2017
comment
@eyllanesc Заштрихованная круглая... на изображении. Под синей полосой прогресса   -  person elgolondrino    schedule 14.03.2017
comment
Разместите соответствующий код или, желательно, минимальный, полный и проверяемый пример.   -  person G.M.    schedule 14.03.2017


Ответы (1)


Я не вижу, в чем здесь проблема, вы можете использовать QPainterPath и добавить к нему полный или частичный путь дуги, а затем нарисовать путь через QPen, используя стиль Qt::DotLine.

Если стандартная пунктирная линия вам не подходит, есть возможность указать собственный шаблон через:

void QPen::setDashPattern(const QVector<qreal> & pattern)

Вот быстрый пример, который выглядит следующим образом:

введите здесь описание изображения

class CPBar : public QWidget {
    Q_OBJECT
    qreal p; // progress 0.0 to 1.0
  public:
    CPBar(QWidget * p = 0) : QWidget(p), p(0) {
      setMinimumSize(208, 208);
    }
    void upd(qreal pp) {
      if (p == pp) return;
      p = pp;
      update();
    }
  void paintEvent(QPaintEvent *) {
    qreal pd = p * 360;
    qreal rd = 360 - pd;
    QPainter p(this);
    p.fillRect(rect(), Qt::white);
    p.translate(4, 4);
    p.setRenderHint(QPainter::Antialiasing);
    QPainterPath path, path2;
    path.moveTo(100, 0);
    path.arcTo(QRectF(0, 0, 200, 200), 90, -pd);
    QPen pen, pen2;
    pen.setCapStyle(Qt::FlatCap);
    pen.setColor(QColor("#30b7e0"));
    pen.setWidth(8);
    p.strokePath(path, pen);
    path2.moveTo(100, 0);
    pen2.setWidth(8);
    pen2.setColor(QColor("#d7d7d7"));
    pen2.setCapStyle(Qt::FlatCap);
    pen2.setDashPattern(QVector<qreal>{0.5, 1.105});
    path2.arcTo(QRectF(0, 0, 200, 200), 90, rd);
    pen2.setDashOffset(2.2);
    p.strokePath(path2, pen2);
  }  
};

class Test : public QWidget {
    Q_OBJECT
  public:
    Test() {
      QVBoxLayout * l = new QVBoxLayout(this);
      CPBar * p = new CPBar;
      QSlider * s = new QSlider(Qt::Horizontal, this);
      s->setMinimum(0);
      s->setMaximum(100);
      l->addWidget(p);
      l->addWidget(s);
      setLayout(l);
      connect(s, &QSlider::valueChanged, [=](){ p->upd((qreal)s->value() / s->maximum());});
    }
};
person dtech    schedule 14.03.2017
comment
Так вы достигнете результата от изображения. - person dtech; 14.03.2017
comment
Я использовал только dashedPattern, но это дало мне несколько кругов в 360. Они были больше, чем я ожидал. - person elgolondrino; 14.03.2017
comment
У вас нет опыта работы с QPainterPath - person elgolondrino; 14.03.2017
comment
@elgolondrino см. QPainterPath::arcTo() функции, которые позволяют указать начальный и конечный угол дуги. doc.qt.io/qt-4.8/qpainterpath.html#arcTo - person dtech; 14.03.2017
comment
Насколько я понимаю, сначала я должен создать rectangle, например. Trapezium... и дать координаты этой функции? - person elgolondrino; 14.03.2017
comment
Как насчет кнопки внутри ProgressBar, есть идеи? - person elgolondrino; 14.03.2017
comment
Я не знаю, о чем вы говорите, формат использования arcTo(sizeRect, startAngle, lengthAngle) - размер прямоугольника - это размер круга, остальное не требует пояснений. Вам, очевидно, нужно больше учиться, прежде чем броситься делать что-то. Прочтите документацию по QPainter и родственным типам. - person dtech; 14.03.2017
comment
Давайте продолжим обсуждение в чате. - person elgolondrino; 14.03.2017