Low performance, timer and label.



  • Hi, i have some problems with QTimer, and label. I wanna create a simple stopwatch, but the time is highly delayed, it's around 15% different, so 30s is equal to 35s.

    Settext function is causing all the problems, and i need it to update the Ms label.

    I am having a lot of bugs with QT, and one of them is it, i have two stopwatches, and one of them was working almost good (Very small percent of delay,almost 0), and the second one, was almost 35% of delay, horrible score.... The second one, is working on the same simple function, and i made it (It's a copy, with different variable name's).

    I was trying to find the issue, why one of the timer, working with a copy of function, was doing that.
    What's funny? When i just deleted the old TabWidget, and created new one (In general, i dont change any settings), now these two timers have the same delay of around 7-10%. I have no idea what's going on, and i have enough.

    If you can do something, cuz i have some bugs with my Qt, sometimes when i delete some objects, then when i press one button, the application crash, and i need to delete, and rebuild the project (It doesn't work if i just press the rebuild button, i lose a lot of time before i notice that).

    Release version is a completely mess up, simple calculations are giving some totally unknown results, basicly 100% is broken, functions are giving stuff from nowhere.

    If i switch to debug version, everything works good. Just the timers still have that low performance.

    I dont know if i should download newer version, and what is causing these problems.



  • hi @Loc888 ,

    from what I read, you have a real mess at your hand ;-)

    Ok let us is break it down a bit

    I am having a lot of bugs with QT, and one of them is it, i have two stopwatches, and one of them was working almost good (Very small percent of delay,almost 0), and the second one, was almost 35% of delay, horrible score.... The second one, is working on the same simple function, and i made it (It's a copy, with different variable name's).

    Why don't you take your working StopWatch and move it into its own class? That why you can make 2 instances of the same base class/object that should behave always the same.

    Release version is a completely mess up, simple calculations are giving some totally unknown results, basicly 100% is broken, functions are giving stuff from nowhere.

    You need to initialize your variables the debug compiler initializes everything with 0, if you don't do it. The release one just takes what happens to be in the memory.



  • @J.Hilk I don't understand what you mean. The problem is with settext function now, when i use it, it's delays the time.



  • @Loc888 said in Low performance, timer and label.:

    I am having a lot of bugs with Qt

    Don't blame the framework. We all did it at least once. It was never the framework's fault.

    Can you post your current code?



  • @VRonin Give me back my wasted time, and i forgive him.



  • @Loc888 said in Low performance, timer and label.:

    Give me back my wasted time

    I could say the same here.

    If you want help, a bit of humility and accepting the fact that there's a 99.9% chance the problem is in your code and not in Qt is a first step



  • @VRonin Ther is nothing to post, simple Qtimer and settext function. That's it.
    The timer refire the function, and set the current time.



  • Can you try this basic example?

    #include <QApplication>
    #include <QTimer>
    #include <QLabel>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QLabel mainWid;
        QTimer mainTimer;
        int counter = 0;
        QObject::connect(&mainTimer,&QTimer::timeout,[&mainWid,&counter]()->void{
            mainWid.setText(QObject::tr("%1 sec").arg(++counter));
        });
        mainTimer.start(1000);
        mainWid.show();
        return a.exec();
    }
    


  • @VRonin It says no matching function.



  • @Loc888 I tested it on my machine Qt 5.10 MSVC2013 x64 Win7. What version of Qt are you running?



  • @VRonin Desktop Qt 5.2.0 MinGW 32bit



  • Then everything should work, you probably just have to enable C++11

    • add CONFIG += c++11 in your .pro file
    • re-run qmake


  • @VRonin It's working, but i need it in MS. It happens because text need to be updated fast, and it cause the problem. If i just run the timer, it's look's fine, but i need to show the time in label..



  • @Loc888 I think you need to be a bit more specific, with what is going on.

    It's working, but i need it in MS. It happens because text need to be updated fast, and it cause the problem. If i just run the timer, it's look's fine, but i need to show the time in label..

    Updating a QLabel's text shouldn't take seconds to update

    to modify the code of @VRonin abit to display time and fast changes:

    #include <QApplication>
    #include <QTimer>
    #include <QLabel>
    #include <QTime>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QLabel mainWid;
        QTimer mainTimer;
        QObject::connect(&mainTimer,&QTimer::timeout,[&mainWid]()->void{
           mainWid.setText(QTime::currentTime().toString("hh.mm.ss.zz"));
        });
        mainTimer.start(10);
        mainWid.show();
    
        return a.exec();
    }
    


  • @J.Hilk I would like to use that, but i don't want current time, i want everything starting from 0.



  • @Loc888
    this code examples are for the purpose of trouble shooting.
    But it's easy enought to adapt.

    #include <QApplication>
    #include <QTimer>
    #include <QLabel>
    #include <QTime>
    #include <QElapsedTimer>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QLabel mainWid;
        QTimer mainTimer;
        QTime time(0,0);
        QElapsedTimer actualTimePassed;
        QObject::connect(&mainTimer,&QTimer::timeout,[&mainWid, &time, &actualTimePassed]()->void{
            time = time.addMSecs(actualTimePassed.elapsed());
            actualTimePassed.start();
            mainWid.setText(time.toString("hh.mm.ss.zzz"));
        });
        actualTimePassed.start();
        mainTimer.start(10);
        mainWid.show();
    
        return a.exec();
    }
    


  • @Loc888 said in Low performance, timer and label.:

    it's working, but i need it in MS

    Unfortunately this is platform dependant. Best you could do is:

    #include <QApplication>
    #include <QTimer>
    #include <QLabel>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QLabel mainWid;
        QTimer mainTimer;
        mainTimer.setTimerType(Qt::PreciseTimer);
        unsigned int counter = 0;
        QObject::connect(&mainTimer,&QTimer::timeout,[&mainWid,&counter]()->void{
            mainWid.setText(QObject::tr("%1 msec").arg(++counter));
            mainWid.repaint();
        });
        mainTimer.start(1);
        mainWid.show();
        return a.exec();
    }
    

    Please note, from http://doc.qt.io/qt-5/qt.html#TimerType-enum:

    Precise timers try to keep millisecond accuracy

    try != will, unfortunately



  • @VRonin Maybe i expressed wrong, but i don't want it in Ms (the total), so 5500 = 5,5s, i want that pattern "mm.ss.zzz" or "mm.ss.zz" , but i want it to start from 0, not from the current time. Is any way to force it? (In sec, ther is no delay when the method update the text).



  • @J.Hilk Guys,i tried J.Hilk code,and it's not working how it should.

    It doesnt help me, it's working, but if i compare the timer to my windows time, the difference is arround 10s (after 2min test), it's too mutch.

    Why it's happening?

    Ps. I tried with "setTimerType(Qt::PreciseTimer);", but still doesn't help...

    ????????



  • My turn ;)

    QLabel label;
    label.setGeometry(100,100,200,50);
     QTimer timer;
     QTime time;
    
     QObject::connect(&timer,&QTimer::timeout,[&time,&label](){
        QTime elapsed=QTime::fromMSecsSinceStartOfDay(time.elapsed());
        label.setText(elapsed.toString("mm:ss:zzz"));
        });
    
    time.start();
    timer.start(100);
    label.show();
    


  • @mpergand

    It seems you are the winner... Why it's working?

    I thought it's working, because you set the delay to 100ms, but even if i change it to 1ms, still working 100%.
    I don't understand why this is working,and the other timers including my, are all retarded... Why it's happening?

    And that's the text update method fault's, i tried to turn off the update, and just set the last result, and it's 100% accurate.



  • I know by experience that to rely on a timer is all wrong.
    You must rely on the system clock for good accuracy.

    And that's the text update method fault's, i tried to turn off the update, and just set the last result, and it's 100% accurate.

    Refresh 1000 times per sec is a heavy task, it consumes about 20% cpu on my machine and serves nothing.
    Timers use the event loop and if the computer is doing heavy tasks, timers triggers might be lost.
    Rely on event loops for a counter is definitely a bad idea.



  • @mpergand Ok, how i can use it with Start, Stop, and Reset button? Because i am trying to move your code to another project, and work with buttons, but when i start the timer, it doesn't do anything.. Still be on 00:00:000, i run it ones, and it start from the actual minutes and seconds, then i modified your code to force it start from 0, and i broke something, now nothing is working...



  • @mpergand Ok, nevermind, i am blind sometimes... I fix it.

    I find the way to restart it, but i have some problems with

    " time.fromString("05:00:000"); "

    It's not working, how should i use that? Or how to stop the time and the timer, and re-start it again but from the last time? (I dont want to reset it when i press the stop button, and then start).



  • You missed an argument and the fact that it's a static function: http://doc.qt.io/qt-5/qtime.html#fromString-1

    time = QTime::fromString("05:00:000","mm:ss:zzz");

    Have you considered QTimeEdit instead of QLabel?



  • @VRonin Still reset when i press the start button, and when i stop and start,it starts from 0.
    Comon, how to fix that? It's almost fixed.


  • Moderators

    @Loc888 said in Low performance, timer and label.:

    @VRonin Still reset when i press the start button, and when i stop and start,it starts from 0.
    Comon, how to fix that? It's almost fixed.

    I suggest that you are showing your actual code snippets and explain what you think they should do.

    Above there are only code snippets from others, not a single snippet from you. Nobody knows what you have taken over into your code. Therefore nobody can give you sound advice.


  • Moderators

    @Loc888 said in Low performance, timer and label.:

    how to stop the time and the timer, and re-start it again but from the last time? (I dont want to reset it when i press the stop button, and then start).

    The Qt timer classes don't have a built-in ability to resume timing like a stopwatch. This means you need to write extra logic to do it.

    1. Start your QElapsedTimer. It starts counting from 0.
    2. Call QElapsedTimer::elapsed() to find out how many milliseconds have passed since the timer was started.
    3. When the user clicks the stop button, store the value of the elapsed time in a variable.
    4. When the user clicks the start the button again, restart your QElapsedTimer. This makes it start from 0 again.
    5. Add the value of the stored variable to QElapsedTimer::elapsed() to get your final stopwatch value.

    @Loc888 said in Low performance, timer and label.:

    Comon, how to fix that? It's almost fixed.

    Since you have not shown your code at all, all the discussions in this thread is only to teach you how to use the time-related classes and functions. We cannot see how you have designed your program, so we cannot tell you how to "fix" your program.

    You need to sit down and think through the logic and maths to implement the stopwatch.



  • @koahnig

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTimer>
    #include <QTime>
    #include <QElapsedTimer>
    #include <QLabel>
    
    
    int Time_Counter;
    
    QString Temp_Time;
    
    QTime elapsed_time_time(0,0);
    
    QTime time(0,0);
    
    
    
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
    
        timer = new QTimer(this);
    
        connect(timer,SIGNAL(timeout()),this,SLOT(Time_Counter_Int()));
    
        
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::Show_Results()
    {
    
        elapsed_time = QTime::fromMSecsSinceStartOfDay(time.elapsed_time());
    
        ui->Timer_Label->setText(elapsed_time.toString("mm:ss:zzz"));
    
        Temp_Time = elapsed_time.toString("mm:ss:zzz");
    
    
    }
    
    void MainWindow::on_Start_Button_clicked()
    {
    
    
        time.start();
    
        timer->start(1);
    
        elapsed_time = elapsed_time.fromString(Temp_Time);
    
    }
    
    void MainWindow::on_Stop_Button_clicked()
    {
    
        timer->stop();
    
        Temp_Time = elapsed_time.toString("mm:ss:zzz");
    
        elapsed_time = elapsed_time.fromString(Temp_Time,"mm:ss:zzz");
    
    
    }
    
    void MainWindow::on_Reset_Button_clicked()
    {
    
        time.restart();
    
        Time_Counter = 0;
    }
    

  • Qt Champions 2016

    Hi
    You connect timer to Time_Counter_Int
    but you do not seem to have such slot ??



  • @mrjj Yes, i see. This is simplified version, don't care about that, i have everything in the place.
    I just need to know, how to reset and stop that timer, and something to convert the value of time, to total MS, because if i just add any variable and increment it, probably it's just 80% accurate, i need to convert the time from timer to total value in MS. I am gonna try, if i can find any way to convert an QString to int value.


  • Qt Champions 2016

    @Loc888 said in Low performance, timer and label.:

    find any way to convert an QString to int value.

    you mean like
    http://doc.qt.io/qt-5/qstring.html#toInt
    `?


  • Moderators

    @Loc888 said in Low performance, timer and label.:

    I just need to know, how to reset and stop that timer

    Have you tried anything at all from my last message?



  • @Loc888 said in Low performance, timer and label.:

    I just need to know, how to reset and stop that timer

    #include <QApplication>
    #include <QTimer>
    #include <QElapsedTimer>
    #include <QTime>
    #include <QLabel>
    #include <QVBoxLayout>
    #include <QPushButton>
    
    int main(int argc, char *argv[])
    {
    
        QApplication app(argc, argv);
    
        int totalTime=0;
        QElapsedTimer time;
        QTimer timer;
        timer.setInterval(99);
    
        QWidget win;
        QLabel* timeLabel=new QLabel("00:00:000");
        QLabel* totalLabel=new QLabel("00:00:000");
        QPushButton* startButton=new QPushButton("Start");
        startButton->setCheckable(true);
        QPushButton* resetButton=new QPushButton("Reset");
    
        QVBoxLayout* vLayout=new QVBoxLayout;
        QHBoxLayout* hLayout=new QHBoxLayout;
    
        hLayout->addWidget(timeLabel);
        hLayout->addWidget(startButton);
        hLayout->addWidget(resetButton);
        vLayout->addLayout(hLayout);
        vLayout->addWidget(totalLabel);
    
        win.setLayout(vLayout);
        win.show();
    
        // timer action
        QObject::connect(&timer,&QTimer::timeout,[&time,&timeLabel](){
            QTime elapsed=QTime::fromMSecsSinceStartOfDay(time.elapsed());
            timeLabel->setText(elapsed.toString("mm:ss:zzz"));
            });
    
        // start/stop action
        QObject::connect(startButton,&QPushButton::toggled,[&](bool checked){
    
            if(checked)
                {
                time.start();
                timer.start();
                resetButton->setEnabled(false);
                startButton->setText("Stop");
                }
            else
                {
                timer.stop();
                int t=time.elapsed();
                totalTime+=t;
                QTime elapsed=QTime::fromMSecsSinceStartOfDay(totalTime);
                totalLabel->setText(elapsed.toString("mm:ss:zzz"));
                // adjust time label
                elapsed=QTime::fromMSecsSinceStartOfDay(t);
                timeLabel->setText(elapsed.toString("mm:ss:zzz"));
                resetButton->setEnabled(true);
                startButton->setText("Start");
                }
    
            });
    
        // reset action
        QObject::connect(resetButton,&QPushButton::clicked,[&timeLabel,&totalLabel,&totalTime](bool checked){
            totalTime=0;
            totalLabel->setText("00:00:000");
            timeLabel->setText("00:00:000");
            });
    
        return app.exec();
    }
    

    Allows multiple start/stop, cumulates each duration in totalTime.



  • @mpergand Ye good one, but too much stuff to add,and it looks a little bit too complicated.
    I try more than few times,and i find much much more better way. I just add:

    time = elapsed.fromMSecsSinceStartOfDay(elapsed.elapsed());

    Just by this one line,now when i press the start button, then stop it and restart, it still counting from the last result. Did you think about that?

    Ps. When i add that line, i had some problems , because the timer doesn't want to reset the value, i fix it fast just by adding some bool variables and control some parts of code.



  • Simplified to display total time only:

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        int totalTime=0;
        QElapsedTimer time;
        QTimer timer;
        timer.setInterval(99);
    
        QWidget win;
        QLabel* totalLabel=new QLabel("00:00:000");
        QPushButton* startButton=new QPushButton("Start");
        startButton->setCheckable(true);
        QPushButton* resetButton=new QPushButton("Reset");
        QHBoxLayout* hLayout=new QHBoxLayout;
    
        hLayout->addWidget(totalLabel);
        hLayout->addWidget(startButton);
        hLayout->addWidget(resetButton);
    
        win.setLayout(hLayout);
        win.show();
    
        // timer action
        QObject::connect(&timer,&QTimer::timeout,[&](){
            QTime elapsed=QTime::fromMSecsSinceStartOfDay(time.elapsed());
            elapsed=elapsed.addMSecs(totalTime);
            totalLabel->setText(elapsed.toString("mm:ss:zzz"));
            });
    
        // start/stop action
        QObject::connect(startButton,&QPushButton::toggled,[&](bool checked){
    
            if(checked)
                {
                time.start();
                timer.start();
                resetButton->setEnabled(false);
                startButton->setText("Stop");
                }
            else
                {
                timer.stop();
                totalTime+=time.elapsed();
                QTime elapsed=QTime::fromMSecsSinceStartOfDay(totalTime);
                totalLabel->setText(elapsed.toString("mm:ss:zzz"));
    
                resetButton->setEnabled(true);
                startButton->setText("Start");
                }
            });
    
        // reset action
        QObject::connect(resetButton,&QPushButton::clicked,[&totalLabel,&totalTime](bool checked){
            totalTime=0;
            totalLabel->setText("00:00:000");
            });
    
        return app.exec();
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.