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. Why is event loop left
Forum Updated to NodeBB v4.3 + New Features

Why is event loop left

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 979 Views 1 Watching
  • 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.
  • D Offline
    D Offline
    Dams
    wrote on last edited by
    #1

    I want to write a small program doing the following:

    • start a single-shot QTimer
    • when it times out, a QMessageBox is shown
    • if button "Continue" is clicked, the box is closed and the timer is restarted
    • if button "Stop" is clicked, the box is closed and the application is exited

    The problem I have is that the event loop is left as soon as I hide the message box. The box is displayed only once. I reproduced my program in a console version, that I can provide here on demand, and it runs as expected. Here is my code. Thanks in advance for your help.

    main.c

    #include <QtGui/QApplication>
    #include "TimedDialog.h"
    
    int main(int argc, char *argv[])
    {
      QApplication app(argc, argv);
    
      TimedDialog dialog(&app, SLOT(quit()));
      dialog.run();
    
      return app.exec();
    }
    

    TimedDialog.h

    #ifndef TIMED_DIALOG_H
    #define TIMED_DIALOG_H
    
    #include <QObject>
    #include <QTimer>
    
    class QMessageBox;
    class QPushButton;
    class QAbstractButton;
    
    class TimedDialog : public QObject
    {
      Q_OBJECT
    
    public:
      TimedDialog(
        QObject const * receiver,
        char const * method);
    
      ~TimedDialog();
    
      void run(void);
    
    signals:
      void stop(void);
    
    private:
      QMessageBox* _box;
      QPushButton* _buttonContinue;
      QPushButton* _buttonStop;
      QTimer _timer;
    
      static int const DELAY = 2 * 1000; // [ms]
    
    private slots:
      void onTimeout(void);
      void onButtonClicked(QAbstractButton * button);
    };
    
    #endif
    

    TimedDialog.cpp

    #include <assert.h>
    #include <QMessageBox>
    #include <QPushButton>
    
    #include "TimedDialog.h"
    
    TimedDialog::TimedDialog(
      QObject const * receiver,
      char const * method)
      : QObject(),
      _box(0),
      _buttonContinue(0),
      _buttonStop(0),
      _timer()
    {
      _box = new QMessageBox();
      _box->setWindowModality(Qt::NonModal);
      _box->setText("Here is my message!");
    
      _buttonContinue = new QPushButton("Continue");
      _box->addButton(_buttonContinue, QMessageBox::AcceptRole);
    
      _buttonStop = new QPushButton("Stop");
      _box->addButton(_buttonStop, QMessageBox::RejectRole);
    
      _timer.setSingleShot(true);
    
      assert(connect(&_timer, SIGNAL(timeout()), this, SLOT(onTimeout())));
      assert(connect(_box, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(onButtonClicked(QAbstractButton *))));
      assert(connect(this, SIGNAL(stop()), receiver, method));
    }
    
    TimedDialog::~TimedDialog()
    {
      delete _box;
    }
    
    void TimedDialog::onTimeout(void)
    {
      _box->show();
    }
    
    void TimedDialog::onButtonClicked(QAbstractButton * button)
    {
      _box->hide();
    
      if (button == _buttonContinue)
      {
        _timer.start(DELAY);
      }
      else
      {
        emit stop();
      }
    }
    
    void TimedDialog::run(void)
    {
      _timer.start(DELAY);
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Pr default the application will exit event loop when no more windows open.
      Which is your case right from beginning :)

      You can turn this off
      http://doc.qt.io/qt-5/qguiapplication.html#quitOnLastWindowClosed-prop

      and then call quit() your self when Stop is clicked.

      1 Reply Last reply
      1
      • D Offline
        D Offline
        Dams
        wrote on last edited by
        #3

        Thanks for your reply, mrjj
        It solves my problem and contributes to extend my learning of Qt! I thought the event loop is left when there is no more event programmed, like my timeout().
        But what do you think now about my console version here below? There is no window at stake and the event loop is not left !? Is it explained by a difference between QApplication and QCoreApplication?

        main.c

        
        #include <QtCore/QCoreApplication>
        #include "MyTimer.h"
        
        int main(int argc, char *argv[])
        {
          QCoreApplication app(argc, argv);
        
          MyTimer myTimer(&app, SLOT(quit()));
          myTimer.start();
        
          return app.exec();
        }
        

        MyTimer.h

        #include <QObject>
        #include <QTimer>
        
        class MyTimer : public QObject
        {
          Q_OBJECT
        
        public:
          MyTimer(QObject const * receiver, char const * method);
          ~MyTimer();
        
          void start(void);
        
        signals:
          void stop(void);
        
        private:
          QTimer _timer;
        
        private slots:
          void onTimeout(void);
        };
        

        MyTimer.cpp

        #include "MyTimer.h"
        #include <iostream>
        #include <assert.h>
        
        MyTimer::MyTimer(QObject const * receiver, char const * method)
          : QObject(),
          _timer()
        {
          _timer.setSingleShot(true);
          assert(connect(&_timer, SIGNAL(timeout(void)), this, SLOT(onTimeout(void))));
          assert(connect(this, SIGNAL(stop()), receiver, method));
        }
        
        MyTimer::~MyTimer(void)
        {
        
        }
        
        void MyTimer::start(void)
        {
          _timer.start(2000);
        }
        
        void MyTimer::onTimeout(void)
        {
          std::cout << "Continue ? ";
          char response('n');
          std::cin >> response;
        
          if (response == 'n')
          {
            emit stop();
          }
          else
          {
            _timer.start(2000);
          }
        }
        
        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          Hi
          Yes - it explained by a difference between QApplication and QCoreApplication?

          QCoreApplication expects you to call quit. QApplication can auto close on
          last top level window close.

          So return app.exec(); does work differently between Core and Application.

          Both does exit on quit().

          It cant wait for "last event" as impossible to know if last timer event seen, will be the last etc.

          1 Reply Last reply
          1
          • D Offline
            D Offline
            Dams
            wrote on last edited by
            #5

            OK. Thanks for all.
            Kind regards.

            1 Reply Last reply
            2

            • Login

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