2

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

我的表单类中有两个计时器:

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

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

这可能是什么原因?

4

2 回答 2

2

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

为什么不只使用一个计时器?您可以走得更远,只使用插槽来进行大小更改事件。其他插槽仅用于更改更改类型:

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
}
于 2012-09-21T10:16:13.487 回答
2

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

为避免这种情况,您可以通过以下方式使连接独一无二:

connect( &oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()), Qt::UniqueConnection);
于 2012-09-21T12:42:51.953 回答