Я использую QTimer
чтобы плавно изменить размер метки: она должна медленно расти, когда я наводю курсор мыши на кнопку, и медленно сворачиваться (уменьшать ее размер, пока она не исчезнет), когда мышь покидает кнопку.
У меня есть два таймера в классе моей формы:
QTimer oTimer, cTimer;//oTimer for expanding, cTimer for collapsing
В конструкторе моей формы я устанавливаю значения таймера и подключаю кнопки mouseOver
а также mouseOut
сигналы к слотам моей формы:
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
}
Согласно вашему коду, QTimer
«s timeout()
Сигнал подключается несколько раз к одному и тому же слоту, и несколько подключений означают, что когда излучается сигнал, слот также будет вызываться несколько раз, что может показаться, что таймер ускоряется.
Чтобы избежать этого, вы можете сделать соединение уникальным с помощью:
connect( &oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()), Qt::UniqueConnection);