每次启动/停止时,QTimer都会变快

QTimer becomes faster with each start/stop

本文关键字:QTimer 启动      更新时间:2023-10-16

我使用QTimer来平滑地更改标签的大小:当我将鼠标悬停在按钮上时,标签应该会慢慢增长,当鼠标离开按钮时,标签会慢慢折叠(减小标签的大小直到消失)。

我有两个计时器在我的形式的课堂上:

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

在表单的构造函数中,我设置计时器的值,并将按钮的mouseOvermouseOut信号连接到表单的插槽:

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)) );

现在,在这些插槽中,我将相应的计时器连接到一个将逐渐改变大小的插槽,然后我启动计时器:

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();
}

之后,标签开始改变其大小:

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()) );
}
}

问题:起初一切都很顺利,标签慢慢打开和关闭。然而,如果它这样做几次,它就会开始越来越快地改变大小(就像计时器的间隔越来越小,但显然不是)。最终,在几次打开/关闭后,当我将鼠标悬停在按钮上时,它立即开始将其大小增加到界限,当鼠标离开按钮时,立即折叠到零大小。

这可能是什么原因?

我建议事件正在等待处理,排队的事件数量会随着时间的推移而增加。可能是因为一个事件在两个定时器事件之间没有完全处理,或者是由于程序的其他部分。

你为什么不只用一个定时器呢?您可以更进一步,只使用插槽进行大小更改事件。其他插槽只是用来更改什么类型的更改:

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
}

根据您的代码,QTimertimeout()信号多次连接到同一个插槽,而多次连接意味着当信号发出时,插槽也会被多次调用,这看起来就像计时器在加速。

为了避免这种情况,您可以使用使连接唯一

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