Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to emulate real time



  • I am using the attached code snippet to track code progress.
    'The "problem " is - the method used has fixed timer ( hardware dependent) -
    QList<QBluetoothHostInfo> information_main = QBluetoothLocalDevice::allDevices();

    That timing dependency causes the main Qt process to sort-of stop while it waits for the method completion - the screen actually goes grey. I am fine with that, however, the
    ui->listWidget_14->addItem calls do not get "processed" until the method finishes.

    Is there a simple way to execute my ui->listWidget_14->addItem calls BEFORE the QList<QBluetoothHostInfo> information_main = QBluetoothLocalDevice::allDevices(); ?

    These are user interface / progress calls and I am not sure if I am ready for multitasking/ multi threading or whatever - if that is the real way to correct this.

    void MainWindow_CAT_TAB::on_pushButton_11_clicked()
    {
    #ifdef TRACE
    .....
    #endif
        ui->listWidget_14->addItem("Start timer TODO ");
    
        // temp return
        // return;
    
        //12/28/2020 adding tracking
        ui->listWidget_14->addItem("START tracking ");
        ui->listWidget_14->addItem("START QBluetoothLocalDevice::allDevices()");
        // not real time for now waits untill done
        QList<QBluetoothHostInfo> information_main = QBluetoothLocalDevice::allDevices();
        ui->listWidget_14->addItem("END QBluetoothLocalDevice::allDevices()");
    


  • @AnneRanch said in How to emulate real time:

    I am using the attached code snippet to track code progress.
    'The "problem " is - the method used has fixed timer ( hardware dependent) -
    QList<QBluetoothHostInfo> information_main = QBluetoothLocalDevice::allDevices();

    That timing dependency causes the main Qt process to sort-of stop while it waits for the method completion - the screen actually goes grey. I am fine with that, however, the
    ui->listWidget_14->addItem calls do not get "processed" until the method finishes.

    What does "processed" mean?

    Is ui->listWidget_14 a QListWidget that isn't showing added items until QBluetoothLocalDevice::allDevices() returns? That's likely because the GUI event loop hasn't been given a chance to run.

    Is there a simple way to execute my ui->listWidget_14->addItem calls BEFORE the QList<QBluetoothHostInfo> information_main = QBluetoothLocalDevice::allDevices(); ?

    It doesn't look like QBluetoothLocal::allDevices() needs to be run from the GUI thread. If you do, anything waiting for the event loop, including painting, will be delayed until it completes.

    These are user interface / progress calls and I am not sure if I am ready for multitasking/ multi threading or whatever - if that is the real way to correct this.

    QtConcurrent::run() will probably result in a better experience:

    void MainWindow_CAT_TAB::on_pushButton_11_clicked()
    {
        ui->listWidget_14->addItem("Start timer TODO ");
        ui->listWidget_14->addItem("START tracking ");
        ui->listWidget_14->addItem("START QBluetoothLocalDevice::allDevices()");
        QFutureWatcher *watcher = new QFutureWatcher(this);
        QObject::connect(watcher, &QFutureWatcher::finished, watcher, &QObject::deleteLater);
        QObject::connect(watcher, QFutureWatcher::resultReadyAt,
            [&](int index){ ui->listWidget_14->addItem("END QBluetoothLocalDevice::allDevices()"); }
        );
        watcher->setFuture(QtConcurrent::run(QBluetoothLocalDevice::allDevices()));
    


  • So in principle I am adding threads to the code , what I was trying to avoid.
    But if it works , no issue here.

    BUT , after adding / modifying the code I get series of errors - starting with this one

    /media/d/QT/QT_PROJECT_CAT/CAT_V1/mainwindow_cat_tab.cpp:327: error: missing template arguments before '*' token
    QFutureWatcher *watcher = new QFutureWatcher(this);
    ^
    and this one which is a "result" of the above error

    /media/d/QT/QT_PROJECT_CAT/CAT_V1/mainwindow_cat_tab.cpp:327: error: 'watcher' was not declared in this scope
    QFutureWatcher *watcher = new QFutureWatcher(this);
    ^
    and the last one

    /media/d/QT/QT_PROJECT_CAT/CAT_V1/mainwindow_cat_tab.cpp:327: error: expected type-specifier before 'QFutureWatcher'
    QFutureWatcher *watcher = new QFutureWatcher(this);
    ^

    Here is my current TEST code using QFutureWatcher

    // replacing
    

    // void MainWindow_CAT_TAB::on_pushButton_11_clicked()
    // {
    #ifdef BYPASS
    ui->listWidget_14->addItem("Start timer TODO ");
    ui->listWidget_14->addItem("START tracking ");
    ui->listWidget_14->addItem("START QBluetoothLocalDevice::allDevices()");
    #endif
    thyis is incoplete - throws errors
    QFutureWatcher *watcher = new QFutureWatcher(this);

    #ifdef BYPASS

        QObject::connect(watcher, &QFutureWatcher::finished, watcher, &QObject::deleteLater);
        QObject::connect(watcher, QFutureWatcher::resultReadyAt,
            [&](int index){ ui->listWidget_14->addItem("END QBluetoothLocalDevice::allDevices()"); }
        );
        watcher->setFuture(QtConcurrent::run(QBluetoothLocalDevice::allDevices()));
    

    #endif

    BTW
    follow-up concern

    When adding new "stuff" to application - how does one determine if adding header is enough and / or when to add QT "module" ?


  • Lifetime Qt Champion

    @AnneRanch said in How to emulate real time:

    follow-up concern
    When adding new "stuff" to application - how does one determine if adding header is enough and / or when to add QT "module" ?

    By reading the small table at the top of the class you want to use documentation.

    For example QFutureWatcher:

    Header:	#include <QFutureWatcher>
    qmake:	QT += core
    Since:	Qt 4.4
    Inherits:	QObject
    


  • @AnneRanch said in How to emulate real time:

    So in principle I am adding threads to the code , what I was trying to avoid.
    But if it works , no issue here.

    What's the motivation for avoiding threads in this case?

    BUT , after adding / modifying the code I get series of errors - starting with this one

    It's pseudocode, intended to concisely convey the idea. Hopefully that and the documentation are enough to bridge the gap to a working program.



  • @jeremy_k said in How to emulate real time:

    @AnneRanch said in How to emulate real time:

    So in principle I am adding threads to the code , what I was trying to avoid.
    But if it works , no issue here.

    What's the motivation for avoiding threads in this case?

    I am all for KISS , but
    But if it works , no issue here.
    So far it is not working as expected.

    BUT , after adding / modifying the code I get series of errors - starting with this one

    It's pseudocode, intended to concisely convey the idea. Hopefully that and the documentation are enough to bridge the gap to a working program.

    It is not much help - it does not explain the concept of "future watcher" AKA creating new thread ( the doc specifically says it is to replace crating plain new thread - so what is the point?) and if it is pseudocode you should have stated so.

    I am sure you will take this in negative way - what what is the point to replacing creation of thread by "new" Qt modules? That is not KISS.

    Sorry but your pseudo code is not helping to fix the actual errors.

    Logically - **if I knew to to fix it I would not ask **
    How difficult is to accept that?

    /media/d/QT/QT_PROJECT_CAT/CAT_V1/mainwindow_cat_tab.cpp:355: error: expected type-specifier before 'QFutureWatcher'
    QFutureWatcher<int> *watcher = new QFutureWatcher(this);
    ^

    So what is legal "type specifier" for QFutureWatcher ?
    I assume my syntax is correct - per doc.



  • @SGaist said in How to emulate real time:

    @AnneRanch said in How to emulate real time:

    follow-up concern
    When adding new "stuff" to application - how does one determine if adding header is enough and / or when to add QT "module" ?

    By reading the small table at the top of the class you want to use documentation.

    For example QFutureWatcher:

    Header:	#include <QFutureWatcher>
    qmake:	QT += core
    Since:	Qt 4.4
    Inherits:	QObject
    

    I'll been doing that , but
    can it be read as
    Header: for "C/C++ "
    qmake: module for "QT " (project)

    They are obviously separate , and in this case "core" is already specified
    and " include " QFutureWatcher.



  • @AnneRanch said in How to emulate real time:

    /media/d/QT/QT_PROJECT_CAT/CAT_V1/mainwindow_cat_tab.cpp:355: error: expected type-specifier before 'QFutureWatcher'
    QFutureWatcher<int> *watcher = new QFutureWatcher(this);
    ^

    It sounds like you are looking for a C++ template usage tutorial. I don't know of a good one. Perhaps someone else does.



  • @jeremy_k said in How to emulate real time:

    @AnneRanch said in How to emulate real time:

    /media/d/QT/QT_PROJECT_CAT/CAT_V1/mainwindow_cat_tab.cpp:355: error: expected type-specifier before 'QFutureWatcher'
    QFutureWatcher<int> *watcher = new QFutureWatcher(this);
    ^

    It sounds like you are looking for a C++ template usage tutorial. I don't know of a good one. Perhaps someone else does.
    I found this one

    https://www.bogotobogo.com/Qt/Qt5_QtConcurrent_QFutureWatcher_QProgressDialog_map.php



  • @AnneRanch BUMP
    Would anybody be interested to help me analyze the tutorial I have posted ?
    It is a very basic and relatively lacking "why" explanations.
    From my point of view it is a reformatted Qt documentation and not really very original.

    BUT the tutorial is a good start and IT WORKS !

    I am having hard time "modifying" the three basic parts to provide "delay" for known time.
    By three basic pasts I see - CPU "time eating " function ( with unexplained "magic numbers" ) , then "configuration dialog" setting # of iterations ( with unexplained "real time" parameters) and finally the actual QProgressDialog ( with assumed default , hence unmentioned parameters ).

    To be clear - I am not asking for "best guess" or "I do not use it, hence I do not know " comments . I am asking to discuss the concept of "continue to run main process while time consuming operation of known length of time runs in the background".



  • @AnneRanch said in How to emulate real time:

    with unexplained "magic numbers"

    The only "magic numbers" I see in this tutorial, are the thread IDs (if you are talking about 0x1d64...) ...
    and just printing the ID of the thread, you are currently in, is far from using any kind of magic at all...

    If you do not understand the tutorial, ask more specific questions. IMO this is self explanatory, but if you are struggling, it won't help you, if somebody else tries to explain it again, using the same or similar phrases.

    Sometimes "why?" is the wrong question ;-)



  • @AnneRanch said in How to emulate real time:

    @AnneRanch BUMP
    Would anybody be interested to help me analyze the tutorial I have posted ?
    It is a very basic and relatively lacking "why" explanations.
    From my point of view it is a reformatted Qt documentation and not really very original.

    BUT the tutorial is a good start and IT WORKS !

    I am having hard time "modifying" the three basic parts to provide "delay" for known time.
    By three basic pasts I see - CPU "time eating " function ( with unexplained "magic numbers" ) , then "configuration dialog" setting # of iterations ( with unexplained "real time" parameters) and finally the actual QProgressDialog ( with assumed default , hence unmentioned parameters ).

    To be clear - I am not asking for "best guess" or "I do not use it, hence I do not know " comments . I am asking to discuss the concept of "continue to run main process while time consuming operation of known length of time runs in the background".

    I have replaced the "spin" - actually a delay function to "eat" cpu cycles.
    That times each iteration to last approximately 1000 mS.

    My goal is to wait for a call which takes approximately 10 seconds to complete.
    In theory 10 iterations each lasting 1 second should work.

    Few problems
    somewhere in QProgressDialog is a small note about "not starting for 4 seconds " . My dialog sits on 0% for approximately 4 seconds , then it jumps to 50% and terminates - obviously before 10 seconds expires. .

    I did add /set some defaults , but the "progress bar " behavior did not change .

        // set defaults
        dialog.setMaximum(100);
        dialog.setRange(10, 100 );
    
    
    Something else , but minor, is bothering me .
    it appears that  the original tutorial is "using"  all CPU's   and calls it "a thread".  It seem odd using all CPU hardware to have a delay simulation of the process which takes time. Looks as delaying ONE CPU / thread would suffice. 
    
    
    

    void spin(int& iteration)
    {

    #ifdef TRACE
    // qDebug() << "QDEBUG TRACE ";
    qDebug () << " delay spin pass #" << iteration ;

    qDebug() << "QDEBUG TRACE TASK \n\t\t emulate the time consuming function \n";
    //qDebug() << "QDEBUG TRACE TASK \n\t\t find nearby BT devices \n";
    

    #ifdef BYPASS
    qDebug() << "file " << FILE;
    qDebug() << "function "<<FUNCTION;
    qDebug() << "@line " << LINE;
    qDebug()<<"TEMPORARY EXIT ";
    //exit(99);
    #endif
    #endif

    // actuall steps MN
    // adding elapsed timer
    

    // int Time_Step = ui->spinBoxIterations_2->text().toInt();

    QElapsedTimer timer;
    timer.start();
    //slowOperation();  // we want to measure the time of this slowOperation()
    // qDebug() << timer.elapsed();
    

    // wait 1000 mS
    do
    {
    //qDebug() << " do / while timer.elapsed()";
    ;
    }while(timer.elapsed() <= 1000); // wait 1000 mS

    #ifdef BYPASS magic numbers
    const int work = 10 * 1000 * 40; // increased by 1000
    volatile int v = 0;
    // the time emulator
    for (int j = 0; j < work; ++j)
    ++v; // step delay loop MN
    #endif

    qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId();
    
    //slowOperation();  // we want to measure the time of this slowOperation()
    
    qDebug() << "Estimated elapsed time " << timer.elapsed()<< " mS";
    

    }
    code_text


Log in to reply