timerEvent and paintEvent different behavior in the same situations



  • I have a game. When Qt::Key_Space is pressed the game is paused (and the text "Paused" appears in place of game field). When the game is lost or won the corresponding texts also appear. The movements (of the ball and 2 players) are made throught timerEvent which repaints the game field every given interval.

    What bothers me, is the way the pause and lost (win) texts work. When the space button is hit, the timer is killed and everything on the game field frozes. But (!) the text "Paused" doesn't appear until i make something with the window (resize it or put down-open up again). At the same time the texts after losing or winning appear almost immediately.
    I can't get why it happens, if the code for all 3 events is the same.

    void Ping::timerEvent(QTimerEvent * e)
    
    {
        Q_UNUSED(e);
    
        w=width();
        h=height();
    
        move_objects();
        check_collision();
        repaint();
    }
    
    void Ping::paintEvent(QPaintEvent * e)
    {
        Q_UNUSED(e);
    
        QPainter painter(this);
    
        if (game_won)
            finish_game(&painter, "You won!");
        else if (paused)
           { finish_game(&painter, "Paused");
           setWindowTitle("PAUSE EVENT PAINT");}
        else if (game_over)
           { finish_game(&painter, "You lost!");
     setWindowTitle("OVER EVENT PAINT");}
        else
            draw_objects(&painter);
    
    }
    
    void Ping::finish_game(QPainter * painter, QString message)
    {
        QFont font("Courier", 15, QFont::DemiBold);
        QFontMetrics fm(font);
        int textWidth = fm.width(message);
    
        painter->setFont(font);
        int h = height();
        int w = width();
    
        painter->translate(QPoint(w/2, h/2));
        painter->drawText(-textWidth/2, 0, message);
    }
    
    void Ping::pause_game() {
    
      if (paused)
      {
        timer_id = startTimer(DELAY);
        paused = false;
      }
    
      else {
    
       killTimer(timer_id);
        paused = true;
    
      }
    

    }

    void Ping::stop_game()
    {
      killTimer(timer_id);
      game_over = true;
      game_started = false;
    }
    
    void Ping::victory()
    {
      killTimer(timer_id);
      game_won = true;
      game_started = false;
    }
    
    

    Plus, I don't fully understand how come the text can appear at all, if in the code the timer is killed before the game_won/game_over is set true (doesn't it mean, that when the timer is killed, the Widget is no longet being repaint, so the paintEvent isn't being called any longer... so there should be no text at all cases!).

    I would be very grateful if somebody could explain this to me.


  • Lifetime Qt Champion

    Hi,

    The widgets get repainted when needed. For example when you move it, when you move another window over it, etc. What your timer does is simply to ask the system to repaint itself.

    When stoping the application you can call update by hand. That should trigger a repaint.

    Hope it helps



  • @SGaist Yes, I understand this. But why the widget repaints itself immediately in stop_game() and victory() while at pause_game() it doesn't?


  • Lifetime Qt Champion

    Do you have anything else that is triggered through stop_game and victory ? e.g. what happens when either game_over or game_won or game_started changes ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.