I'm attempting to create a program to display notifications on my desktop. I've started by using a QLabel that pops up whenever I change my volume.
Here I have a function that takes a QLabel and string as parameters and updates the label with the string's text:
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();
}
This function is called in a loop in the main that waits every 1 second and checks if the volume has changed. My issue is that whenever I increase the volume over more than one second, the dialog ends up displaying twice (or more), which makes sense because it checks again and the volume is not the same as it was a second ago.
What I'd like to do is have the label update continuously for the three seconds that is showing, but as far as I know, you can just
while( loop.exec() ) { //UpdateLabel }
How can I accomplish this? It would also help to be able to then have it show for longer if the volume is still increasing/decreasing.
Thanks in advance!
Edit:
Here's what the main function, which calls the displayNotif, looks like:
#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();
}
It is not necessary to use while True for this repetitive task, just use a QTimer
, when using QEventLoop
you do not leave any way to update any component of the 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, ¤t_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"
in the following link you will find the complete example.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.