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. Qt DrawPie location and rotation issue
Qt 6.11 is out! See what's new in the release blog

Qt DrawPie location and rotation issue

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 940 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.
  • S Offline
    S Offline
    star673
    wrote on last edited by
    #1

    Hello all,

    I would like to make an application which includes rotation widget inside a circle. I started this with the AnalogClock example in qt. I wouldd like to rotate a quarter pie (quarter circle) instead of gauge. My problem is I cannot locate the pie in the center of my circle.
    Below picture, I barely locate the pi in the center of circle but I would like to make the pi bigger than below picture.
    Screenshot from 2022-03-30 10-24-37.png

    I realized that all paintings locate inside of rectangle like below.

    Screenshot from 2022-03-30 10-25-04.png

    When I change the drawPie function parameters rectangle's location change and rotates based on on edge point. I can make the ractange bigger but this time drawPie center changes too like the last visual.

    Screenshot from 2022-03-30 10-26-22.png

    ![Screenshot from 2022-03-3

    0 10-26-59.png](https://ddgobkiprc33d.cloudfront.net/8e3b33a3-3cc7-4d3f-9ca5-475f3df170bc.png)

    You can check the code below. It is modifed from the AnalogClock example. I would like to draw a quarter pie and make it the rotate endlessly. Any help will be appreciated. If you have a better opinion, I would like hear that too.

    AnalogClock::AnalogClock(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::AnalogClock)
    {
        ui->setupUi(this);
    
        QTimer *timer = new QTimer(this);
    
        connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update));
    
        timer->start(1000);
    
        setWindowTitle(tr("Analog Clock"));
        resize(200, 200);
    }
    
    void AnalogClock::paintEvent(QPaintEvent *)
    {
    
    
    
        QColor minuteColor(0, 127, 127, 191);
    
        int side = qMin(width(), height());
        QTime time = QTime::currentTime();
    
        QPainter painter(this);
    
        painter.setRenderHint(QPainter::Antialiasing);
    
        painter.translate(width() / 2, height() / 2);
    
        painter.scale(side / 200.0, side / 200.0);
    
    
        painter.setPen(Qt::NoPen);
    
        qreal radius=10;
        qreal startAngle=0;
        qreal span=60;
    
    
    
    
        for (int i = 0; i < 12; ++i) {
            painter.drawLine(88, 0, 96, 0);
            painter.rotate(30.0);
        }
    
    
        painter.setBrush(minuteColor);
    
    
        painter.save();
    
        painter.rotate(6.0 *  time.second() );
        //painter.drawConvexPolygon(minuteHand, 3);
    
        QRect rect( -radius, -radius, radius*10, radius*10);
    
        painter.drawPie( rect, startAngle*16, span*16 );
    
    
       // painter.fillRect(rect,QBrush(Qt::green));
        painter.restore();
    
    
    
        painter.setPen(minuteColor);
    
    
    
        for (int j = 0; j < 60; ++j) {
                painter.drawLine(92, 0, 96, 0);
            painter.rotate(6.0);
        }
    
    }
    
    
    1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by
      #2

      Hi, I think it's easier if you use the QGraphicsView/QGraphicsScene stuff, made a sample program for you:
      Start with an empty vanilla widgets app, then change your mainwindow.cpp to look like this:

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      #include "qgraphicsview.h"
      #include "qgraphicsscene.h"
      #include "QGraphicsLineItem"
      #include "qvector.h"
      #include "qtimer.h"
      
      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
      
          auto graphicsView = new QGraphicsView(this);
          graphicsView->setGeometry(0,0,width(),height());
          auto scene = new QGraphicsScene(this);
      
          auto diameter          = qMin(graphicsView->width(),graphicsView->height()) / 1.05;
          auto radius            = diameter / 2;
          auto minuteLineLength  = radius / 20;
          auto minuteLineWidth   = 1;
          auto pieLineLength     = radius - minuteLineLength;
          auto pieLineWidth      = 5;
          auto origo             = QPointF(radius, radius);
          auto timerMilliseconds = 33;   // <--- the speed (33 means one rotation takes 2 seconds) 
      
      // draw the minutes
          for (int m = 0; (m < 60); ++m)
          {
              auto degrees = m * 6 - 90;   // start at 12 o'clock (north)
              auto radians = (degrees / 360.0f) * 2 * 3.141592653;
              auto point0 = origo + QPointF(pieLineLength * cos(radians),pieLineLength * sin(radians));
              auto point1 = origo + QPointF(radius    * cos(radians),radius    * sin(radians));
              scene->addLine(QLineF(point0,point1),QPen(QBrush(Qt::black),minuteLineWidth));
          }
      
      // store the pie lines here
          QList<QGraphicsLineItem*> lPieLines;
      
      // draw the pie lines
          for (int p = 0; (p < 360); ++p)
          {
              auto degrees = p - 90;   // start at 12 o'clock (north)
              auto radians = (degrees / 360.0f) * 2 * 3.141592653;
              auto point0 = origo;
              auto point1 = origo + QPointF(pieLineLength * cos(radians),pieLineLength * sin(radians));
              lPieLines.append(scene->addLine(QLineF(point0,point1),QPen(QBrush(Qt::green),pieLineWidth)));
      
              lPieLines.constLast()->setVisible(p < 90);
          }
      
      // all lines added, set the scene
          graphicsView->setScene(scene);
      
      // start the party
          auto timer = new QTimer(this);
          connect(timer,&QTimer::timeout,this,[lPieLines]
          {
              static int degrees = 0;
      
          // step clockwise
              ++degrees;
      
          // go thru all of the pie lines
              for (int l = 0; (l < 360); ++l)
                  lPieLines.at((l + degrees) % 360)->setVisible(l < 90);
          } );
          timer->start(timerMilliseconds);
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      

      and it should look like this: (and rotate nicely :-)
      Screenshot 2022-03-30 at 21.00.57.png

      1 Reply Last reply
      1
      • E Offline
        E Offline
        ELIF
        wrote on last edited by
        #3

        @hskoglund said in Qt DrawPie location and rotation issue:

        for (int m = 0; (m < 60); ++m)
        {
        auto degrees = m * 6 - 90; // start at 12 o'clock (north)
        auto radians = (degrees / 360.0f) * 2 * 3.141592653;
        auto point0 = origo + QPointF(pieLineLength * cos(radians),pieLineLength * sin(radians));
        auto point1 = origo + QPointF(radius * cos(radians),radius * sin(radians));
        scene->addLine(QLineF(point0,point1),QPen(QBrush(Qt::black),minuteLineWidth));
        }

        Thank you very much :) Really appreciate it ! Best regards.

        1 Reply Last reply
        0
        • hskoglundH Offline
          hskoglundH Offline
          hskoglund
          wrote on last edited by
          #4

          Glad you liked it, it's a fun little demo.

          BTW, I realized the timer code it a bit wasteful, it hides/shows all the 360 pie lines every time, but actually you only need to update the edges (the forward edge: one line needs to be turned on and the line at trailing edge needs to be hidden).

          So here is a better optimized "start the party" code:

          / start the party (revised version)
              auto timer = new QTimer(this);
              connect(timer,&QTimer::timeout,this,[lPieLines]
              {
                  static int degrees = 0;
          
                  lPieLines.at((0 +  degrees) % 360)->setVisible(false);
                  lPieLines.at((90 + degrees) % 360)->setVisible(true);
          
              // rotate once clockwise
                  ++degrees;
              } );
          
              timer->start(timerMilliseconds);
          

          Also I was wrong stating that a full rotation with a milleseconds setting of 33 takes 2 seconds, of course it should be 12 seconds (i.e. 30 per second for a total of 360 steps).

          S 1 Reply Last reply
          1
          • hskoglundH hskoglund

            Glad you liked it, it's a fun little demo.

            BTW, I realized the timer code it a bit wasteful, it hides/shows all the 360 pie lines every time, but actually you only need to update the edges (the forward edge: one line needs to be turned on and the line at trailing edge needs to be hidden).

            So here is a better optimized "start the party" code:

            / start the party (revised version)
                auto timer = new QTimer(this);
                connect(timer,&QTimer::timeout,this,[lPieLines]
                {
                    static int degrees = 0;
            
                    lPieLines.at((0 +  degrees) % 360)->setVisible(false);
                    lPieLines.at((90 + degrees) % 360)->setVisible(true);
            
                // rotate once clockwise
                    ++degrees;
                } );
            
                timer->start(timerMilliseconds);
            

            Also I was wrong stating that a full rotation with a milleseconds setting of 33 takes 2 seconds, of course it should be 12 seconds (i.e. 30 per second for a total of 360 steps).

            S Offline
            S Offline
            star673
            wrote on last edited by
            #5

            @hskoglund

            Thank you so much sir. You helped me a lot. Best wishes.

            1 Reply Last reply
            0
            • E Offline
              E Offline
              ELIF
              wrote on last edited by ELIF
              #6
              This post is deleted!
              1 Reply Last reply
              0

              • Login

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