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. QTimer is not making a time delay

QTimer is not making a time delay

Scheduled Pinned Locked Moved General and Desktop
9 Posts 4 Posters 3.2k 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.
  • R Offline
    R Offline
    rotpar
    wrote on last edited by
    #1

    Hi,

    I have two QPushButton and a QSlider. I Want to press the startButton and the position of the slider should increment, wait 1 sec and increment again and so on. When I hit the stopButton I want the loop of the slider incrementation to stop.

    Right now I'm trying this, but it's just jumping right to the slider's last position or the program is crashing. Of course I'm not writing down code, that is irrelevant for this problem in my opinion

    In FVolumeplayer the player is displayed as a dockwidget in the mainwindow. If a button is clicked I emit signals and handle the events in the mainwindow.
    FVolumePlayer.h
    @class FVolumePlayerWidget: public QDockWidget
    {
    Q_OBJECT

    public:

    enum State {Paused=0, Playing=1, Stopped=2};
    State playerState;
    State state() {return playerState;}
    //...
    public slots:
    void on_playButton_clicked_slot();
    void on_stopButton_clicked_slot();

    signals:
    void play();
    void stop();
    };@

    FVolumePlayer.cpp
    @FVolumePlayerWidget::FVolumePlayerWidget(QMainWindow parent)
    : QDockWidget(tr("Timeline"),(QWidget
    )parent), playerState(Stopped)
    {
    //...
    playButton = new QPushButton();
    playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
    connect(playButton, SIGNAL(clicked()), this, SLOT(on_playButton_clicked_slot()));
    stopButton = new QPushButton();
    stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
    connect(stopButton, SIGNAL(clicked()), this, SLOT(on_stopButton_clicked_slot()));

         horizontalSlider = new QSlider(Qt::Horizontal, this);
        //...
    

    }

    void FVolumePlayerWidget::on_playButton_clicked_slot()
    {
    emit play();
    }

    void FVolumePlayerWidget::on_stopButton_clicked_slot()
    {
    emit stop();
    }@

    In the mainwindow I connect the signals from the player to slots and check for the current state to make the player act like desired.
    FMainWIndow.cpp
    @FMainWindow::FMainWindow(ProcessorNetwork *network, QWidget *parent, Qt::WindowFlags flags)
    : network_(network), QMainWindow(parent, flags), volumeCount(0)

    {
    vlmPlayWidget_ = new FVolumePlayerWidget(this);
    addDockWidget(Qt::BottomDockWidgetArea , vlmPlayWidget_);

        connect(vlmPlayWidget_, SIGNAL(play()), this, SLOT(play_slot()));
    

    connect(vlmPlayWidget_, SIGNAL(stop()), this, SLOT(stop_slot()));
    }

    void FMainWindow::play_slot()
    {
    if (vlmPlayWidget_->state() == FVolumePlayerWidget::Playing)
    {
    QMessageBox::critical(this, "Error", "Volume Player is already running");
    return;
    }

    if(vlmPlayWidget_->state() == FVolumePlayerWidget::Stopped)
    {
    vlmPlayWidget_->playerState = FVolumePlayerWidget::Playing;
    }
    QEventLoop evt;

    while(vlmPlayWidget_->playerState != FVolumePlayerWidget::Stopped)
    {
    evt.processEvents();
    if(vlmPlayWidget_->playerState == FVolumePlayerWidget::Playing)
    {
    volumeCount = vlmPlayWidget_->horizontalSlider->value()+1;
    vlmPlayWidget_->horizontalSlider->setValue(volumeCount);
    QTimer::singleShot(1000, this, SLOT(vlmPlayWidget_->horizontalSlider->update()));
    }
    }
    vlmPlayWidget_->playerState = FVolumePlayerWidget::Stopped;
    }

    void FMainWindow::stop_slot(){
    vlmPlayWidget_->playerState = FVolumePlayerWidget::Stopped;
    //volumeCount = 0;
    vlmPlayWidget_->horizontalSlider->setValue(volumeCount);

    }@

    As I said, the QTimer is not making a time delay of 1 second between each iteration and the slider is moving to his last position immediatly. And I read I nead an eventloop somwhere, but I don't know if I put it in the right lines. So how do I get this working the right way? Or do you need more information to help me?

    1 Reply Last reply
    0
    • Z Offline
      Z Offline
      zerbp
      wrote on last edited by
      #2

      try

      QTimer::singleShot(1000, vlmPlayWidget_->horizontalSlider, SLOT(update()));

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        bq. @QEventLoop evt;

        while(vlmPlayWidget_->playerState != FVolumePlayerWidget::Stopped)
        {
        evt.processEvents();
        if(vlmPlayWidget_->playerState == FVolumePlayerWidget::Playing)
        {
        volumeCount = vlmPlayWidget_->horizontalSlider->value()+1;
        vlmPlayWidget_->horizontalSlider->setValue(volumeCount);
        QTimer::singleShot(1000, this, SLOT(vlmPlayWidget_->horizontalSlider->update()));
        }@

        This is wrong in many ways:

        • evt is another event loop that you don't start so calling processEvents on that object won't have any effect. Also it won't have the effect you are thinking about.
        • Your call to QTimer::singleShot is also wrong, it should be (delay, object_that_has_the_slot, SLOT(slot_of_your_object())

        I would recommend that you refactor a bit your code. You are trying to do several simple things in a very convoluted manner.

        Changing a slider value each second (raw idea):
        Have a QTimer as class member
        Set it to run each second
        Connect the timer timeout signal to a slot where you increment the slider value.
        Connect your start button clicked signal to the timer start slot
        Connect your stop button clicked signal to the timer stop slot

        Since you have all your buttons/slider in FVolumePlayer, do all the work in that widget, MainWindow does not need at all to know the internals of your widget.

        Hope it helps

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • R Offline
          R Offline
          rotpar
          wrote on last edited by
          #4

          Okay, I tried to implement your Idea like this in the FVolumePlayer.cpp:

          @volumeTimer = new QTimer(this);
          connect(volumeTimer, SIGNAL(timeout()), this, SLOT(play()));
          volumeTimer->setInterval(1000);

          playButton = new QPushButton();
          playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
          connect(playButton, SIGNAL(clicked()), volumeTimer, SLOT(start()));
          stopButton = new QPushButton();
          stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
          connect(stopButton, SIGNAL(clicked()), volumeTimer, SLOT(stop()));@

          and

          @void FVolumePlayerWidget::play()
          {
          horizontalSlider->setValue(horizontalSlider->value()+1);
          }@

          But It just does nothing when I click the playButton. Am I missing something? play() is declared as public slot in FVolumePlayer.h

          1 Reply Last reply
          0
          • K Offline
            K Offline
            KA51O
            wrote on last edited by
            #5

            The code looks fine. Maybe check if all the connect calls return true. Also do you have a running eventloop ? Like do you call QApplication::exec() or QCoreApplication::exec() somewhere?

            1 Reply Last reply
            0
            • R Offline
              R Offline
              rotpar
              wrote on last edited by
              #6

              bq. Also do you have a running eventloop ? Like do you call QApplication::exec() or QCoreApplication::exec() somewhere?

              Yes, I do in the main.cpp

              bq. The code looks fine. Maybe check if all the connect calls return true.

              How do I check this?

              1 Reply Last reply
              0
              • K Offline
                K Offline
                KA51O
                wrote on last edited by
                #7

                connect returns a boolean just do this
                @
                bool connectTest = connect(volumeTimer, SIGNAL(timeout()), this, SLOT(play()));
                @
                also have you checked if you place a break point in the play() method if you ever enter that function?

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  rotpar
                  wrote on last edited by
                  #8

                  Okay thanks it's already working, the code is fine. Turns out, the moment I pushed the button,my computer was running very slow and closed the program maybe a second too soon. I compiled again and now it's working.

                  Thanks alot to all of you, you really helped me out. My brain was blowing out steam already.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    You're welcome !

                    Since your problem's gone, you can update the thread's title to solved so other forum users may know that a solution has been found :)

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    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