Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to draw a smooth arc
Forum Updated to NodeBB v4.3 + New Features

How to draw a smooth arc

Scheduled Pinned Locked Moved Solved General and Desktop
2 Posts 1 Posters 967 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    nanor
    wrote on last edited by nanor
    #1

    I have three LineEdits in dialog window. When the user types something in them, an arc is drawn(the arc degree is based on the number of empty lineEdits).
    I have overrided and implemented QPaintEvent and set the slots to LineEdits textChanged signal, and my code worked fine. In order to draw a smooth arc, I have used QPropertyanimation(which exists in the following code) and got the warning: "you're trying to animate a non-existing property pen of your QObject". After searching about this warning, I found out that I should override and implement timerEvent() instead of using QPropertyanimation.
    I would appreciate if someone could help me implementing timerEvent or suggest another way in order to draw a smooth arc.

    Here is the code:

    dialog.h:

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    #include <QPainter>
    #include <QPen>
    #include <QRectF>
    #include <QSlider>
    #include <QLineEdit>
    #include <QPropertyAnimation>
    
    namespace Ui {
    class Dialog;
    }
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget *parent = 0);
        ~Dialog();
        QPainter p;
        QPen pen;
        double progress;
        int startAngle;
        int spanAngle;
        QLineEdit *lineEdit_1;
        QLineEdit *lineEdit_2 ;
        QLineEdit *lineEdit_3;
        QPropertyAnimation *animation;
    
    
    
    public slots:
        void setProgress();
        void setProgress2();
        void setProgress3();
    
    
    protected:
        void paintEvent(QPaintEvent *);
        
    
    private:
        Ui::Dialog *ui;
    
    };
    
    #endif // DIALOG_H
    
    

    dialog.cpp:

    #include "dialog.h"
    #include "ui_dialog.h"
    #include <QConicalGradient>
    #include <QPropertyAnimation>
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    
        lineEdit_1 = new QLineEdit(this);
        lineEdit_1->setGeometry(400,50,100,50);
        lineEdit_1->show();
    
    
        lineEdit_2 = new QLineEdit(this);
        lineEdit_2->setGeometry(400,150,100,50);
        lineEdit_2->show();
    
    
        lineEdit_3 = new QLineEdit(this);
        lineEdit_3->setGeometry(400,250,100,50);
        lineEdit_3->show();
    
         connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress()));
         connect(lineEdit_2, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress2()));
         connect(lineEdit_3, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress3()));
    
    }
    
    Dialog::~Dialog()
    {
        delete ui;
    }
    
    void Dialog::setProgress()
    {
    
        if(lineEdit_1->text().isEmpty())
        {
            if(lineEdit_2->text().isEmpty() && lineEdit_3->text().isEmpty())
            {
                progress = 0;
                this->update();
            }
            else if(lineEdit_2->text().isEmpty() || lineEdit_3->text().isEmpty())
            {
                progress = 120;
                this->update();
            }
            else
            {
                progress = 240;
                this->update();
            }
    
        }
        else
        {
            if(lineEdit_2->text().isEmpty() && lineEdit_3->text().isEmpty())
            {
                progress = 120;
                this->update();
            }
            else if(lineEdit_2->text().isEmpty() || lineEdit_3->text().isEmpty())
            {
                progress = 240;
                this->update();
            }
            else
            {
                progress = 360;
                this->update();
            }
    
        }
    
    
    
    }
    
    void Dialog::setProgress2()
    {
    
        if(lineEdit_2->text().isEmpty())
        {
            if(lineEdit_1->text().isEmpty() && lineEdit_3->text().isEmpty())
            {
                progress = 0;
                this->update();
            }
            else if(lineEdit_1->text().isEmpty() || lineEdit_3->text().isEmpty())
            {
                progress = 120;
                this->update();
            }
            else
            {
                progress = 240;
                this->update();
            }
    
        }
        else
        {
            if(lineEdit_1->text().isEmpty() && lineEdit_3->text().isEmpty())
            {
                progress = 120;
                this->update();
            }
            else if(lineEdit_1->text().isEmpty() || lineEdit_3->text().isEmpty())
            {
                progress = 240;
                this->update();
            }
            else
            {
                progress = 360;
                this->update();
            }
    
        }
    
    
    }
    
    
    void Dialog::setProgress3()
    {
        if(lineEdit_3->text().isEmpty())
        {
    
            if(lineEdit_1->text().isEmpty() && lineEdit_2->text().isEmpty())
            {
                progress = 0;
                this->update();
            }
            else if(lineEdit_1->text().isEmpty() || lineEdit_2->text().isEmpty())
            {
                progress = 120;
                this->update();
            }
            else
            {
                progress = 240;
                this->update();
            }
        }
        else
        {
    
    
            if(lineEdit_1->text().isEmpty() && lineEdit_2->text().isEmpty())
            {
                progress = 120;
                this->update();
            }
            else if(lineEdit_1->text().isEmpty() || lineEdit_2->text().isEmpty())
            {
                progress = 240;
                this->update();
            }
            else
            {
                progress = 360;
                this->update();
            }
    
    
        }
    
    }
    
    
    
    
    void Dialog::paintEvent(QPaintEvent *)
    {
        QPainter p(this);
    
        QRectF rectangle(100.0, 70.0, 100.0, 100.0);
    
        QConicalGradient gradient;
        gradient.setCenter(rectangle.center());
        gradient.setAngle(30);
        gradient.setColorAt(0, QColor(178, 255, 246));
        gradient.setColorAt(1, QColor(5, 44, 50));
    
    
        QPen pen(QBrush(gradient), 10);
        p.setPen(pen);
        p.setRenderHint(QPainter::Antialiasing);
    
       int startAngle = 0 * 16;
       int spanAngle = progress * 16;
       p.drawArc(rectangle, startAngle, spanAngle);
    
    
       //.............make the arc smooth.............//
       animation = new QPropertyAnimation(this,"pen");
       animation->setDuration(1000);
       animation->setStartValue(QRect(460,30,853,114));
       animation->setEndValue(QRect(460,30,853,824));
       animation->start();
    
    
    
    
        //.........numbers in the center......//
        QPainter p2(this);
        QPen pen2;
        pen2.setWidth(7);
        pen2.setColor(Qt::black);
        p2.setPen(pen2);
    
    
        if(progress==120)
        {
            p2.drawText(rectangle,Qt::AlignCenter,QString::number(33.3)+" %");
        }
        else if(progress==240)
        {
            p2.drawText(rectangle,Qt::AlignCenter,QString::number(66.6)+" %");
        }
        else if(progress==360)
        {
            p2.drawText(rectangle,Qt::AlignCenter,QString::number(100)+" %");
        }
        else
        {
            p2.drawText(rectangle,Qt::AlignCenter,QString::number(0)+" %");
        }
    
    }
    
    
    

    main.cpp:

    #include "dialog.h"
    #include <QApplication>
    #include <QSlider>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        Dialog w;
        w.show();
    
    
        return a.exec();
    }
    
    

    The output:

    output.png

    1 Reply Last reply
    0
    • N Offline
      N Offline
      nanor
      wrote on last edited by
      #2

      I found the solution!
      I set SmoothArc slot to these three lineEdits and then I used QVarientAnimation inside this slot. Then using the onValueChanged(QVariant) slot which is specific for QVarientAnimation class, I changed the degree of arc which is changing from 0 to the progress value.
      Here is the following code:

      dialog.h:

      #ifndef DIALOG_H
      #define DIALOG_H
      
      #include <QDialog>
      #include <QLineEdit>
      #include <QVariantAnimation>
      #include <QPainter>
      
      namespace Ui {
      class Dialog;
      }
      
      class Dialog : public QDialog
      {
       Q_OBJECT
      
      public:
       explicit Dialog(QWidget *parent = 0);
       ~Dialog();
      
       QLineEdit *lineEdit_1;
       QLineEdit *lineEdit_2;
       QLineEdit *lineEdit_3;
       QVariantAnimation *animation;
       int progress;
      
      
      public slots:
       void setProgress();
       void setProgress2();
       void setProgress3();
       void SmoothArc();
       void onValueChanged(const QVariant &value);
      
      
      
      private:
       Ui::Dialog *ui;
       int mvalue = 0;
      
      
      protected:
        void paintEvent(QPaintEvent *);
      };
      
      #endif // DIALOG_H
      
      

      dialog.cpp:

      #include "dialog.h"
      #include "ui_dialog.h"
      
      Dialog::Dialog(QWidget *parent) :
          QDialog(parent),
          ui(new Ui::Dialog)
      
      {
          ui->setupUi(this);
      
          lineEdit_1 = new QLineEdit(this);
          lineEdit_1->setGeometry(400,50,100,50);
          lineEdit_1->show();
      
          lineEdit_2 = new QLineEdit(this);
          lineEdit_2->setGeometry(400,150,100,50);
          lineEdit_2->show();
      
      
          lineEdit_3 = new QLineEdit(this);
          lineEdit_3->setGeometry(400,250,100,50);
          lineEdit_3->show();
      
      
      
          connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress()));
          connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(SmoothArc()));
      
          connect(lineEdit_2, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress2()));
          connect(lineEdit_2, SIGNAL(textChanged(const QString &)), this, SLOT(SmoothArc()));
      
      
          connect(lineEdit_3, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress3()));
          connect(lineEdit_3, SIGNAL(textChanged(const QString &)), this, SLOT(SmoothArc()));
      
      }
      
      Dialog::~Dialog()
      {
          delete ui;
      }
      
      void Dialog::setProgress()
      {
      
          if(lineEdit_1->text().isEmpty())
          {
              if(lineEdit_2->text().isEmpty() && lineEdit_3->text().isEmpty())
              {
                  progress = 0;
                  this->update();
              }
              else if(lineEdit_2->text().isEmpty() || lineEdit_3->text().isEmpty())
              {
                  progress = 120;
                  this->update();
              }
              else
              {
                  progress = 240;
                  this->update();
              }
      
          }
          else
          {
              if(lineEdit_2->text().isEmpty() && lineEdit_3->text().isEmpty())
              {
                  progress = 120;
                  this->update();
              }
              else if(lineEdit_2->text().isEmpty() || lineEdit_3->text().isEmpty())
              {
                  progress = 240;
                  this->update();
              }
              else
              {
                  progress = 360;
                  this->update();
              }
      
          }
      
      
      
      }
      
      
      void Dialog::setProgress2()
      {
      
          if(lineEdit_2->text().isEmpty())
          {
              if(lineEdit_1->text().isEmpty() && lineEdit_3->text().isEmpty())
              {
                  progress = 0;
                  this->update();
              }
              else if(lineEdit_1->text().isEmpty() || lineEdit_3->text().isEmpty())
              {
                  progress = 120;
                  this->update();
              }
              else
              {
                  progress = 240;
                  this->update();
              }
      
          }
          else
          {
              if(lineEdit_1->text().isEmpty() && lineEdit_3->text().isEmpty())
              {
                  progress = 120;
                  this->update();
              }
              else if(lineEdit_1->text().isEmpty() || lineEdit_3->text().isEmpty())
              {
                  progress = 240;
                  this->update();
              }
              else
              {
                  progress = 360;
                  this->update();
              }
      
          }
      
      
      }
      
      void Dialog::setProgress3()
      {
          if(lineEdit_3->text().isEmpty())
          {
      
              if(lineEdit_1->text().isEmpty() && lineEdit_2->text().isEmpty())
              {
                  progress = 0;
                  this->update();
              }
              else if(lineEdit_1->text().isEmpty() || lineEdit_2->text().isEmpty())
              {
                  progress = 120;
                  this->update();
              }
              else
              {
                  progress = 240;
                  this->update();
              }
          }
          else
          {
      
      
              if(lineEdit_1->text().isEmpty() && lineEdit_2->text().isEmpty())
              {
                  progress = 120;
                  this->update();
              }
              else if(lineEdit_1->text().isEmpty() || lineEdit_2->text().isEmpty())
              {
                  progress = 240;
                  this->update();
              }
              else
              {
                  progress = 360;
                  this->update();
              }
      
      
          }
      
      }
      
      
      void Dialog::paintEvent(QPaintEvent *)
      {
          QPainter p(this);
      
          QRectF rectangle(100.0, 70.0, 100.0, 100.0);
      
          QConicalGradient gradient;
          gradient.setCenter(rectangle.center());
          gradient.setAngle(30);
          gradient.setColorAt(0, QColor(178, 255, 246));
          gradient.setColorAt(1, QColor(5, 44, 50));
      
      
          QPen pen(QBrush(gradient), 10);
          p.setPen(pen);
          p.setRenderHint(QPainter::Antialiasing);
      
         int startAngle = 0;
         int spanAngle = mvalue * 16;
      
         p.drawArc(rectangle, startAngle, spanAngle);
      
      
      }
      
      //.......................draw smooth arc.....................//
      void Dialog::SmoothArc()
      {
      
           animation = new QVariantAnimation(this);
           animation->setStartValue(mvalue);
           animation->setEndValue(progress);
           animation->setDuration(1500);
           animation->start();
      
           connect(animation, SIGNAL(valueChanged(QVariant)), this, SLOT(onValueChanged(QVariant)));
      
      }
      
      void Dialog::onValueChanged(const QVariant &value)
      {
          mvalue = value.toDouble();
          update();
      
      }
      
      

      main.cpp:

      #include "dialog.h"
      #include <QApplication>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          Dialog w;
          w.show();
      
          return a.exec();
      }
      
      
      1 Reply Last reply
      1

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved