Results 1 to 8 of 8

Thread: How to connect QTimer with QPaintEvent?

  1. #1
    Join Date
    Mar 2012
    Posts
    9
    Platforms
    Windows Symbian S60

    Exclamation How to connect QTimer with QPaintEvent?

    Good Evening!

    Is it possible to connect the Qtimer with QPaintEvent. In my project I have already created the QPaintEvent, and drew the Ellipse, now I want to create the qtimer and after timeout I want that my existing ellipse will move to another place on my widget. Is it possible to make that? I have made it but my ellipse does not move. Please help me. I really hope on your help! Thanks!
    widget.h
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QtGui>
    5.  
    6. class Widget : public QWidget
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. Widget(QWidget *parent = 0);
    12. ~Widget();
    13.  
    14. QGridLayout *grid;
    15. QWidget *widget1;
    16. //QPen *pen;
    17. QBrush *brush, *brush1;
    18. QTimer *timer;
    19.  
    20. public slots:
    21. void paintEvent(QPaintEvent *);
    22. void paintEvent1(QPaintEvent *);
    23.  
    24. };
    25.  
    26. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 

    main.cpp
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "widget.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. Widget w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    widget.cpp
    Qt Code:
    1. #include "widget.h"
    2.  
    3. Widget::Widget(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. grid = new QGridLayout;
    7. widget1= new QWidget;
    8.  
    9. timer = new QTimer(this);
    10.  
    11. grid->addWidget(widget1,0,6,0,6);
    12. this->setLayout(grid);
    13.  
    14.  
    15. QPainter painter(this);
    16. //pen = new QPen;
    17. brush = new QBrush;
    18. brush1= new QBrush;
    19. //pen->setColor(Qt::blue);
    20. brush->setColor(Qt::red);
    21.  
    22.  
    23. connect(timer, SIGNAL(timeout()), this,SLOT(paintEvent1(QPaintEvent*)));
    24. timer->start(5);
    25.  
    26.  
    27.  
    28.  
    29.  
    30.  
    31.  
    32. }
    33.  
    34. Widget::~Widget()
    35. {
    36.  
    37. }
    38. void Widget::paintEvent(QPaintEvent *)
    39. {
    40.  
    41. QPainter painter(this);
    42.  
    43.  
    44. painter.setBrush(Qt::SolidPattern);
    45. /*QRadialGradient radialGradient(50, 50, 50, 70, 70);
    46.   radialGradient.setColorAt(0.0, Qt::white);
    47.   radialGradient.setColorAt(0.2, Qt::green);
    48.   radialGradient.setColorAt(1.0, Qt::black);
    49.   painter.setBrush(radialGradient);*/
    50. painter.drawEllipse(0,0,125,125);
    51.  
    52.  
    53. update();
    54.  
    55.  
    56.  
    57. }
    58. void Widget::paintEvent1(QPaintEvent *)
    59. {
    60.  
    61. QPainter painter1(this);
    62. painter1.setBrush(Qt::SolidPattern);
    63. painter1.drawEllipse(0,0,185,185);
    64. update();
    65.  
    66.  
    67. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Asus_G72GX; 1st May 2012 at 15:25.

  2. #2
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to connect QTimer with QPaintEvent?

    Qt Code:
    1. connect( timer, SIGNAL( timeout() ), widget, SLOT( update() ) );
    To copy to clipboard, switch view to plain text mode 
    This will trigger paint event.

    Btw I hope that you're not moving your ellipse in the paint event...

  3. #3
    Join Date
    Mar 2012
    Posts
    9
    Platforms
    Windows Symbian S60

    Default Re: How to connect QTimer with QPaintEvent?

    Quote Originally Posted by Spitfire View Post
    Qt Code:
    1. connect( timer, SIGNAL( timeout() ), widget, SLOT( update() ) );
    To copy to clipboard, switch view to plain text mode 
    This will trigger paint event.

    Btw I hope that you're not moving your ellipse in the paint event...
    Thank you for reply! I have remake code. But Qt started to ignore qtimer, 2nd ellipse is drowing immediately. Is there any possibility to destroy first ellipse after drawing 2nd? Or maybe it is impossible in QPaintEvent. Maybe try to do some stuff with QPoint?
    Qt Code:
    1. #include "widget.h"
    2.  
    3. Widget::Widget(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. grid = new QGridLayout;
    7. widget1= new QWidget;
    8.  
    9. timer = new QTimer(this);
    10.  
    11. grid->addWidget(widget1,0,6,0,6);
    12. this->setLayout(grid);
    13.  
    14.  
    15. QPainter painter(this);
    16. //pen = new QPen;
    17. brush = new QBrush;
    18. brush1= new QBrush;
    19. //pen->setColor(Qt::blue);
    20. brush->setColor(Qt::red);
    21.  
    22.  
    23. connect(timer, SIGNAL(timeout()), widget1,SLOT(update()));
    24.  
    25. timer->start(20);
    26.  
    27.  
    28.  
    29.  
    30.  
    31.  
    32.  
    33. }
    34.  
    35. Widget::~Widget()
    36. {
    37.  
    38. }
    39. void Widget::paintEvent(QPaintEvent *)
    40. {
    41.  
    42. QPainter painter(this);
    43.  
    44.  
    45. painter.setBrush(Qt::SolidPattern);
    46. /*QRadialGradient radialGradient(50, 50, 50, 70, 70);
    47.   radialGradient.setColorAt(0.0, Qt::white);
    48.   radialGradient.setColorAt(0.2, Qt::green);
    49.   radialGradient.setColorAt(1.0, Qt::black);
    50.   painter.setBrush(radialGradient);*/
    51. painter.drawEllipse(0,0,125,125);
    52.  
    53.  
    54. update();
    55.  
    56.  
    57.  
    58. }
    59. void Widget::update()
    60. {
    61.  
    62. QPainter painter(this);
    63.  
    64. painter.drawEllipse(0,0,185,185);
    65.  
    66.  
    67.  
    68. }
    To copy to clipboard, switch view to plain text mode 



    Header.h
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QtGui>
    5.  
    6. class Widget : public QWidget
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. Widget(QWidget *parent = 0);
    12. ~Widget();
    13.  
    14. QWidget *widget1;
    15. //QPen *pen;
    16. QBrush *brush, *brush1;
    17. QTimer *timer;
    18.  
    19. public slots:
    20. void paintEvent(QPaintEvent *);
    21. void update();
    22.  
    23. };
    24.  
    25. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to connect QTimer with QPaintEvent?

    Some thoughts:
    • QWidget::update() is a slot your widget already has, not something you need to reimplement.
    • Calling update() inside the paintEvent() makes no sense.
    • Connecting the timer to a generic QWidget (that you are not painting) will not cause your widget to paint.


    Here is a complete example of a custom widget: Analogue Clock Example
    Last edited by ChrisW67; 2nd May 2012 at 07:28.

  5. #5
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to connect QTimer with QPaintEvent?

    some more points:

    connect(timer, SIGNAL(timeout()), this,SLOT(paintEvent1(QPaintEvent*)));

    you cant connect signals with X number of arguments to to slots with more than X arguments.

    You shouldn't be making multiple paint event methods. THE paintEvent will always get called on update, YOUR paint event will only get called on timeout. Why should there be two? (There definitely should not be)

    You don't need to 'destroy' anything in paint event - paint event always starts with a clean canvas.


    But Qt started to ignore qtimer, 2nd ellipse is drowing immediately.
    It is only doing what you tell it to do. You call update() in paintevent. Your misguided addition of your own update() method draws the second ellipse at the same time as the first. Please read your own code more carefully.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  6. #6
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to connect QTimer with QPaintEvent?

    I'm in a good mood today, so I'll give you ready-made (compilable) solution, if this isn't enough, then you need to go back to the books (you should anyway, most of stuff guys above are saying is in the documentation)
    Qt Code:
    1. // header
    2. #ifndef MAINWINDOW_H
    3. #define MAINWINDOW_H
    4.  
    5. #include <QtGui/QMainWindow>
    6.  
    7. class MainWindow : public QMainWindow
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. MainWindow( QWidget* parent = 0 );
    13.  
    14. public slots:
    15. void redrawEllipse( void );
    16.  
    17. protected:
    18. void paintEvent( QPaintEvent* event );
    19.  
    20. private:
    21. int radius;
    22. };
    23.  
    24. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // implementation
    2. #include "mainwindow.h"
    3.  
    4. #include <QPainter>
    5. #include <QTimer>
    6.  
    7. MainWindow::MainWindow( QWidget* p )
    8. :
    9. radius( 1 )
    10. {
    11. QTimer* t = new QTimer( this );
    12. connect( t, SIGNAL( timeout() ), this, SLOT( redrawEllipse() ) );
    13. t->start( 10 );
    14. }
    15.  
    16. void MainWindow::redrawEllipse( void )
    17. {
    18. radius += 2;
    19.  
    20. if( radius > qMin( this->width()/2, this->height()/2 ) )
    21. {
    22. radius = 1;
    23. }
    24.  
    25. this->update();
    26. }
    27.  
    28. void MainWindow::paintEvent( QPaintEvent* e )
    29. {
    30. Q_UNUSED( e );
    31.  
    32. QPainter p( this );
    33. p.drawEllipse( this->rect().center(), this->radius, this->radius );
    34. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Mar 2012
    Posts
    9
    Platforms
    Windows Symbian S60

    Default Re: How to connect QTimer with QPaintEvent?

    Spitfire great thanks for you that you helped me with this!
    Anyway I have discussed this problem with my lector he showed me that it possiblee to move ellipse if we declare a coordinates for it like a dx ,dy,x,y.
    The final result must be close to this images below:



    But I have collided that Qt does not see a z coordinate. So I make them by x,y. My code result is close to those sample images, but I was not able to move the ball to the right and upwards. Maybe is it possible to change the values? Thanks again!
    Widget.h
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QtGui>
    5.  
    6. class Widget : public QWidget
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. Widget(QWidget *parent = 0);
    12. ~Widget();
    13.  
    14. //QWidget *widget1;
    15. QPen *pen;
    16. QBrush *brush, *brush1;
    17. //QTimer *timer;
    18. QMatrix matrix;
    19.  
    20. void paintEvent(QPaintEvent *);
    21. int x;
    22. int x2;
    23.  
    24. int y;
    25. int y2;
    26. int dx, dy;
    27. int dx2, dy2;
    28.  
    29. void timerEvent(QTimerEvent *);
    30. void timerEvent1(QTimerEvent *);
    31. public slots:
    32. void move();
    33. };
    34.  
    35. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 

    Main.cpp

    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "widget.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. Widget w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    Widget.cpp
    Qt Code:
    1. #include "widget.h"
    2.  
    3.  
    4. Widget::Widget(QWidget *parent)
    5. : QWidget(parent)
    6. {
    7. grid = new QGridLayout;
    8.  
    9. QPainter painter(this);
    10.  
    11. //widget1= new QWidget;
    12. //grid->addWidget(widget1,0,6,0,6);
    13. this->setLayout(grid);
    14.  
    15. pen = new QPen;
    16. brush = new QBrush;
    17.  
    18. //pen->setColor(Qt::blue);
    19. brush->setColor(Qt::red);
    20. //timer = new QTimer(this);
    21. /*x = 10;
    22.  
    23. dx = 5;
    24. dy = 10;
    25. y =30;*/
    26.  
    27.  
    28. x = 10;
    29. dx = 5;
    30. dy = 10;
    31. y =30;
    32.  
    33.  
    34. x2 = 10;
    35. dx2 = 5;
    36. dy2 = 10;
    37. y2 =30;
    38.  
    39.  
    40.  
    41.  
    42.  
    43.  
    44.  
    45.  
    46.  
    47. //connect(timer, SIGNAL(timeout()), this,SLOT(move()));
    48. //timer->start(3000);
    49. this->startTimer(100);
    50.  
    51. }
    52.  
    53. void Widget::timerEvent(QTimerEvent *){
    54.  
    55. x = x + dx;
    56.  
    57.  
    58. if(x >=165) dx = -5;
    59. if(x <0) dx = 5;
    60.  
    61.  
    62. y = y + dy;
    63.  
    64.  
    65. if(y <=-165) dy = 10;
    66. if(y >0) dy = -10;
    67.  
    68.  
    69.  
    70.  
    71.  
    72.  
    73.  
    74. // 2nd leg for blue ball
    75.  
    76.  
    77. x2 = x2+ dx2;
    78.  
    79.  
    80. if(x2 >=165) dx2 = 5;
    81. if(x2 <0) dx2 = -5;
    82. if(x2>5) dx2=1;
    83.  
    84.  
    85. y2 = y2- dy2;
    86.  
    87.  
    88. if(y2 <=-165) dy2 = 10;
    89. if(y2 >0) dy2 = -10;
    90. if(y2>-10) dx2=15;
    91. /*if(y2>=100) dy2=5;
    92.   if(y2>0) dy2=-5;*/
    93.  
    94. /* y2 = y2 + dy2;
    95.  
    96.   if(y2 <=100) dy2 = 1;
    97.   if(y2 >0) dy2 = -1;*/
    98.  
    99.  
    100. update();
    101. }
    102.  
    103.  
    104. Widget::~Widget()
    105. {
    106.  
    107. }
    108. void Widget::paintEvent(QPaintEvent *)
    109. {
    110. QPainter painter (this);
    111. painter.setBrush(Qt::red);
    112.  
    113.  
    114. /*QRadialGradient radialGradient(50, 50, 50, 70, 70);
    115.   radialGradient.setColorAt(0.0, Qt::white);
    116.   radialGradient.setColorAt(0.2, Qt::green);
    117.   radialGradient.setColorAt(1.0, Qt::black);
    118.   painter.setBrush(radialGradient);*/
    119. painter.drawEllipse(x,y,40,40);
    120. painter.setBrush(Qt::blue);
    121. painter.drawEllipse(x2,y2,10,10);
    122.  
    123. }
    124. void Widget::move()
    125.  
    126. {
    127. QPainter painter (this);
    128. painter.drawEllipse(0,0,165,165);
    129. }
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to connect QTimer with QPaintEvent?

    You should be using OO approach.

    Create a class 'ball', give it what you need and then move it around.
    Parent widget can be canvas for the ball to move around.

    To move ball in oposite direction, just multiply dx and/or dy by -1 every time you hit some edge.

    here's example ball class:
    Qt Code:
    1. class Ball : public QWidget
    2. {
    3. Q_OBJECT
    4. public:
    5. Ball( int dx, int dy, QWidget* parent = 0 )
    6. :
    7. QWidget( parent ),
    8. dx( dx ),
    9. dy( dy )
    10. {
    11. this->setFixedSize( 20, 20 );
    12. }
    13.  
    14. public slots:
    15. void advance( void )
    16. {
    17. QPoint p = this->pos();
    18.  
    19. int x = p.x() + this->dx;
    20. if( x < 0 )
    21. {
    22. x = 0;
    23. this->dx *= -1;
    24. }
    25. else if( x + this->width() > this->parentWidget()->width() )
    26. {
    27. x = this->parentWidget()->width() - this->width();
    28. this->dx *= -1;
    29. }
    30.  
    31. int y = p.y() + this->dy;
    32. if( y < 0 )
    33. {
    34. y = 0;
    35. this->dy *= -1;
    36. }
    37. else if( y + this->height() > this->parentWidget()->height() )
    38. {
    39. y = this->parentWidget()->height() - this->height();
    40. this->dy *= -1;
    41. }
    42.  
    43. this->move( x, y );
    44. }
    45.  
    46. protected:
    47. void paintEvent( QPaintEvent* e )
    48. {
    49. Q_UNUSED( e );
    50.  
    51. QPainter p( this );
    52. pp.addEllipse( this->rect() );
    53. p.fillPath( pp, Qt::red );
    54. }
    55.  
    56. private:
    57. int dx;
    58. int dy;
    59. };
    To copy to clipboard, switch view to plain text mode 
    Don't come back if you won't be able to figure out how to use it...

Similar Threads

  1. QMouseEvent on QPaintEvent
    By GUIman in forum Newbie
    Replies: 7
    Last Post: 1st March 2011, 08:51
  2. How to sendEvent QPaintEvent ?
    By SABROG in forum Qt Programming
    Replies: 23
    Last Post: 28th May 2009, 21:55
  3. Can we connect QTimer::SingleShot with a slot taking arguments?
    By maverick_pol in forum Qt Programming
    Replies: 4
    Last Post: 17th September 2008, 18:02
  4. QPaintEvent on button click?
    By vishal.chauhan in forum Qt Programming
    Replies: 1
    Last Post: 5th June 2007, 08:44
  5. Inheritance and QpaintEvent
    By djoul in forum Qt Programming
    Replies: 22
    Last Post: 5th July 2006, 13:56

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.