QTimer becomes faster with each start/stop

被刻印的时光 ゝ 提交于 2019-12-24 02:55:17

问题


I'm using a QTimer to smoothly change the size of a label: it should slowly grow when I hover the mouse over a button, and slowly collapse (decrease it's size until it dissapears) when the mouse leaves the button.

I have two timers in my form's class:

QTimer oTimer, cTimer;//oTimer for expanding, cTimer for collapsing

In my form's constructor, I'm setting the timer's values and connecting the button's mouseOver and mouseOut signals to my form's slots:

oTimer.setInterval( 25 );
cTimer.setInterval( 25 );

connect( ui.Button, 
         SIGNAL(mouseEntered(QString)), 
         this, 
         SLOT(expandHorizontally(QString)) );
connect( ui.Button, 
         SIGNAL(mouseLeft(QString)), 
         this, 
         SLOT(compactHorizontally(QString)) );

Now, in these slots I connect the corresponding timer to a slot that will gradually change the size, and then I start the timer:

void cForm::expandHorizontally(const QString & str)
{
    ui.Text->setText( str ); 
    connect( &oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()) );
    cTimer.stop();//if the label is collapsing at the moment, stop it
    disconnect( &cTimer, SIGNAL(timeout()) );
    oTimer.start();//start expanding
}

void cForm::compactHorizontally(const QString &)
{
    connect( &cTimer, SIGNAL(timeout()), this, SLOT(decreaseHSize()) );
    oTimer.stop();
    disconnect( &oTimer, SIGNAL(timeout()) );
    cTimer.start();
}

After that, the label starts changing it's size:

void cForm::increaseHSize()
{
    if( ui.Text->width() < 120 )
    {
        //increase the size a bit if it hasn't reached the bound yet
        ui.Text->setFixedWidth( ui.Text->width() + 10 );
    }
    else
    {
        ui.Text->setFixedWidth( 120 );//Set the desired size
        oTimer.stop();//stop the timer
        disconnect( &oTimer, SIGNAL(timeout()) );//disconnect the timer's signal
    }
}

void cForm::decreaseHSize()
{
    if( ui.Text->width() > 0 )
    {
        ui.Text->setFixedWidth( ui.Text->width() - 10 );
    }
    else
    {
        ui.Text->setFixedWidth( 0 );
        cTimer.stop();
        disconnect( &cTimer, SIGNAL(timeout()) );
    }
}

The problem: Everything works smoothly at first, the label slowly opens and closes. However, if it does so a couple of times, it starts changing the size faster and faster each time (just as if the timer's interval was getting smaller and smaller, but it obviously isn't). Eventually after a couple of openings/closes it just begins to immediately increase it's size up to the bound when I hover the mouse over the button, and immediately collapse to the zero size when the mouse goes away from the button.

What could be the reason for that?


回答1:


I would suggest that events are waiting to be processed, and the number of queued events increase with time. Maybe because an event is not completely processed between two timer events or due to the other parts of the program.

Why don't you use only one timer? You can go even further, by using only slot for size change events. The other slots are just there for changing what type of change:

void cForm::connectStuff(){
    connect( &oTimer, SIGNAL(timeout()), this, SLOT(changeSize()) );
    connect( 
          ui.Button, 
          SIGNAL(mouseEntered(QString)), 
          this, 
          SLOT(expandHorizontally()) 
    );
    connect( 
          ui.Button, 
          SIGNAL(mouseLeft(QString)), 
          this, 
          SLOT(compactHorizontally()) 
    );
}

void cForm::expandHorizontally(){
      shouldExpand = true;
}

void cForm::compactHorizontally(){
      shouldExpand = false;
}

void cForm::changeSize(){
     if(shouldExpand)
        increaseHSize();//call the function which expand
     else
        decreaseHSize();//call the function which compact
}



回答2:


According to your code, QTimer's timeout() signal is connected multiple times to the same slot, and multiple connections mean that when the signal is emitted, the slot will be called multiples times too, which would seem as if the timer was accelerating.

To avoid that you can make the connection unique with:

connect( &oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()), Qt::UniqueConnection);


来源:https://stackoverflow.com/questions/12528184/qtimer-becomes-faster-with-each-start-stop

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!