C++ 如何在一段时间内更新QLabel?

C++ 如何在一段时间内更新QLabel?,c++,qt,qlabel,C++,Qt,Qlabel,我正在尝试创建一个程序,以便在桌面上显示通知。我首先使用了一个QLabel,每当我更改音量时,它就会弹出 这里我有一个函数,它将QLabel和字符串作为参数,并使用字符串的文本更新标签: void displayNotif (QLabel* label, int labelText) { labelStr = QString::number(labelText) + "% volume"; label -> setText(labelStr); label ->

我正在尝试创建一个程序,以便在桌面上显示通知。我首先使用了一个QLabel,每当我更改音量时,它就会弹出

这里我有一个函数,它将QLabel和字符串作为参数,并使用字符串的文本更新标签:

void displayNotif (QLabel* label, int labelText) {
    labelStr = QString::number(labelText) + "% volume";
    label -> setText(labelStr);
    label -> raise();
    label -> show();

    //Animation
    QPropertyAnimation *slideIn = new QPropertyAnimation(label, "pos");
    slideIn->setDuration(750);
    slideIn->setStartValue(QPoint(1800, 30));
    slideIn->setEndValue(QPoint(1250, 30));
    slideIn->setEasingCurve(QEasingCurve::InBack);
    slideIn->start();


    // Wait 3 seconds 
    QEventLoop loop;
    QTimer::singleShot(3000, &loop, SLOT(quit()));
    loop.exec();

    // Close block
    label -> hide();
}
此函数在main中的循环中调用,该循环每1秒等待一次,并检查卷是否已更改。我的问题是,每当我将音量增加超过一秒钟时,对话框最终会显示两次(或更多),这是有意义的,因为它会再次检查,并且音量与一秒钟前不一样

我想做的是让标签在显示的三秒钟内持续更新,但据我所知,您可以

while( loop.exec() ) { //UpdateLabel }
我怎样才能做到这一点?如果音量仍在增加/减少,则能够让它显示更长时间也会有所帮助

提前谢谢

编辑:

下面是调用displayNotif的主函数的样子:

#include <QApplication>
#include <QLabel>
#include <QProcess>
#include <QTimer>
#include "getBattery.h"
#include "getVolume.h"
#include "displayNotif.h"
#include "AnimatedLabel.h"

int main(int argc, char *argv[]) {

    QApplication app(argc, argv);

    // Create Label
    QLabel *hello = new QLabel();

    int vol;
    vol = getVolume();
    QEventLoop loop;

    while (true) {
        //Check if volume is updated
        if (getVolume() != vol) {
            vol = getVolume();
            displayNotif (hello, vol);
        }

        // Wait .2 second
        QTimer::singleShot(200, &loop, SLOT(quit()));
        loop.exec();

    }
    return app.exec();
}
#包括
#包括
#包括
#包括
#包括“getBattery.h”
#包括“getVolume.h”
#包括“displayNotif.h”
#包括“AnimatedLabel.h”
int main(int argc,char*argv[]){
QApplication应用程序(argc、argv);
//创建标签
QLabel*hello=newqlabel();
国际卷;
vol=getVolume();
QEventLoop循环;
while(true){
//检查卷是否已更新
如果(getVolume()!=vol){
vol=getVolume();
displayNotif(你好,vol);
}
//等等,2秒钟
QTimer::单发(200,&循环,插槽(quit());
loop.exec();
}
返回app.exec();
}

对于此重复任务,不必使用while True,只需使用
QTimer
,当使用
QEventLoop
时,您不会留下任何方法来更新GUI的任何组件

#include <QApplication>
#include <QLabel>
#include <QTimer>
#include <QDebug>
#include <QPropertyAnimation>

class NotifyLabel: public QLabel{
    Q_OBJECT
    QTimer timer{this};
    QPropertyAnimation slideIn{this, "pos"};
public:
    NotifyLabel(){
        timer.setSingleShot(true);
        timer.setInterval(3000);
        connect(&timer, &QTimer::timeout, this, &NotifyLabel::hide);
        slideIn.setDuration(750);
        slideIn.setStartValue(QPoint(1800, 30));
        slideIn.setEndValue(QPoint(1250, 30));
        slideIn.setEasingCurve(QEasingCurve::InBack);
    }
    void displayNotif(int value){
        if(timer.isActive()){
            timer.stop();
        }
        else
            slideIn.start();
        setText(QString("%1% volume").arg(value));
        show();
        timer.start();
    }
};

static int  getVolume(){
    // emulate volume
    return 1+ rand() % 3;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    NotifyLabel w;
    QTimer timer;

    int current_vol;

    QObject::connect(&timer, &QTimer::timeout, [&w, &current_vol](){
        int update_vol = getVolume();

        qDebug()<<update_vol;

        if(current_vol != update_vol){
            w.displayNotif(update_vol);
        }
        current_vol = update_vol;
    });
    timer.start(2000);
    return a.exec();
}

#include "main.moc"
#包括
#包括
#包括
#包括
#包括
类NotifyLabel:公共QLabel{
Q_对象
QTimer定时器{this};
QPropertyAnimation slideIn{this,“pos”};
公众:
NotifyLabel(){
定时器设置单脉冲(真);
定时器设置间隔(3000);
连接(&timer、&QTimer::timeout、this、&NotifyLabel::hide);
slideIn.setDuration(750);
slideIn.setStartValue(QPoint(1800,30));
slideIn.setEndValue(QPoint(1250,30));
slideIn.setEasingCurve(QEasingCurve::InBack);
}
void displayNotif(int值){
if(timer.isActive()){
timer.stop();
}
其他的
slideIn.start();
setText(QString(“%1%卷”).arg(值));
show();
timer.start();
}
};
静态int getVolume(){
//模拟音量
返回1+rand()%3;
}
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
标签w;
定时器;
国际货币流通量;
QObject::connect(&timer,&QTimer::timeout,[&w,¤t_vol](){
int update_vol=getVolume();

qDebug()对于此重复任务,不必使用while True,只需使用
QTimer
,当使用
QEventLoop
时,您不会留下任何方法来更新GUI的任何组件

#include <QApplication>
#include <QLabel>
#include <QTimer>
#include <QDebug>
#include <QPropertyAnimation>

class NotifyLabel: public QLabel{
    Q_OBJECT
    QTimer timer{this};
    QPropertyAnimation slideIn{this, "pos"};
public:
    NotifyLabel(){
        timer.setSingleShot(true);
        timer.setInterval(3000);
        connect(&timer, &QTimer::timeout, this, &NotifyLabel::hide);
        slideIn.setDuration(750);
        slideIn.setStartValue(QPoint(1800, 30));
        slideIn.setEndValue(QPoint(1250, 30));
        slideIn.setEasingCurve(QEasingCurve::InBack);
    }
    void displayNotif(int value){
        if(timer.isActive()){
            timer.stop();
        }
        else
            slideIn.start();
        setText(QString("%1% volume").arg(value));
        show();
        timer.start();
    }
};

static int  getVolume(){
    // emulate volume
    return 1+ rand() % 3;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    NotifyLabel w;
    QTimer timer;

    int current_vol;

    QObject::connect(&timer, &QTimer::timeout, [&w, &current_vol](){
        int update_vol = getVolume();

        qDebug()<<update_vol;

        if(current_vol != update_vol){
            w.displayNotif(update_vol);
        }
        current_vol = update_vol;
    });
    timer.start(2000);
    return a.exec();
}

#include "main.moc"
#包括
#包括
#包括
#包括
#包括
类NotifyLabel:公共QLabel{
Q_对象
QTimer定时器{this};
QPropertyAnimation slideIn{this,“pos”};
公众:
NotifyLabel(){
定时器设置单脉冲(真);
定时器设置间隔(3000);
连接(&timer、&QTimer::timeout、this、&NotifyLabel::hide);
slideIn.setDuration(750);
slideIn.setStartValue(QPoint(1800,30));
slideIn.setEndValue(QPoint(1250,30));
slideIn.setEasingCurve(QEasingCurve::InBack);
}
void displayNotif(int值){
if(timer.isActive()){
timer.stop();
}
其他的
slideIn.start();
setText(QString(“%1%卷”).arg(值));
show();
timer.start();
}
};
静态int getVolume(){
//模拟音量
返回1+rand()%3;
}
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
标签w;
定时器;
国际货币流通量;
QObject::connect(&timer,&QTimer::timeout,[&w,¤t_vol](){
int update_vol=getVolume();

qDebug()如何通过信号调用displayNotif?不,我让这个程序作为守护进程运行,所以我只有一段时间(true)循环检查卷并在卷发生变化时调用DisplayNot。在GUI中为True吗?您可以提供项目的详细信息,因为exec阻止了以下行。当然,对此表示抱歉。我编辑了文章以包含我的主函数。它还不完全完整,因为我没有添加getVolume函数,但它非常简单。希望没问题。getVolume()需要很长时间才能执行,还是几乎是瞬间执行的?如何通过信号调用displayNotif??不,我让这个程序作为守护进程运行,所以我只有一段时间(真)循环检查卷并在卷发生变化时调用DisplayNot。在GUI中为True吗?您可以提供项目的详细信息,因为exec阻止了以下行。当然,对此表示抱歉。我编辑了文章以包含我的主函数。它还不完全完整,因为我没有添加getVolume函数,但它非常简单。希望没问题。getVolume()需要很长时间才能执行,还是几乎是瞬间执行?谢谢!这非常适合我的问题。不幸的是,在我尝试将代码“最小化”时,我在对话框中添加了一个QPropertyAnimation片段,这样它就可以从我的屏幕右侧滑入了。下面是它的样子:
QPropertyAnimation*slideIn=newQPropertyAnimation(w,“pos”);slideIn->setDuration(750);slideIn->setStartValue(QPoint(1800,30));slideIn->setEndValue(QPoint(1250,30));slideIn->setEasingCurve(QEasingCurve::InBack);slideIn->start();
我可以在哪里将其添加到代码中?如果我将其放入conect循环,它将执行动画