Qt World Summit: Submit your Presentation


Using QTimer in main() (not in a class)?



  • Hi,

    What I want to achieve is a timer instance created within my main function, that on timeout calls another function within main.cpp .

    Normally the syntax of connecting the right signal and slot would be something like this:

    QObject::connect(&timer, SIGNAL(timeout()), &RECEIVER_CLASS_INSTANCE, SLOT(RECEIVER_CLASS_FUNCTION()));
    

    which normally would be fine, but the app I am making does not have a MainWindow and this is happening within the main function (its a simple app and I don't need to use the MainWindow setup). So unless theres a special way to use it it seems that I cannot connect the timer signal to the slot this way as I don't have a class instance to give the connect function, and I can't use "this" since again, its not a class instance.

    In the wiki I noticed a newer way to use connect mentioned here: https://wiki.qt.io/New_Signal_Slot_Syntax

    connect(sender, &Sender::valueChanged, someFunction);
    

    which would allow me to just connect a signal to a function like a desire. So i tried:

        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, slotUpdate());
    

    but then I get:

    main.cpp:40: error: C2665: 'QObject::connect': none of the 3 overloads could convert all the argument types
    

    So, I'm a little stuck on how to pull this off. Anyone know how to do this ? ><

    Thanks in advance.



  • Hi! There's just a typo in your connect statement :-)

    #include <QApplication>
    #include <QDebug>
    #include <QTimer>
    
    void someFunction()
    {
        qDebug() << "Some function";
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, someFunction);
        QObject::connect(&timer, &QTimer::timeout, []() { qDebug() << "Lambda"; });
        timer.start(500);
    
        return a.exec();
    }
    


  • Woops...

    That did the trick, thanks!



  • #include <iostream>
    #include "opencv2/core.hpp"
    #include "opencv2/imgproc.hpp"
    #include "opencv2/highgui.hpp"
    #include "opencv2/ml.hpp"
    #include "opencv2/objdetect.hpp"
    #include "opencv2/videoio.hpp"
    #include "QtWidgets/QApplication"
    #include "QtWidgets/QLabel"
    #include "QtWidgets/QAction"
    #include "QtWidgets/QApplication"
    #include "QtWidgets/QButtonGroup"
    #include "QtWidgets/QHeaderView"
    #include "QtWidgets/QLCDNumber"
    #include "QtWidgets/QMainWindow"
    #include "QtWidgets/QMenuBar"
    #include "QtWidgets/QPushButton"
    #include "QtWidgets/QStatusBar"
    #include "QtWidgets/QToolBar"
    #include "QtWidgets/QWidget"
    #include "QtWidgets/QLayout"
    #include "QtWidgets/QMainWindow"
    #include "QtCore/QTimer"

    using namespace std;
    using namespace cv;

    static void mySlot(QPushButton* Btn)
    {
    cout << "button2 clicked" << endl;
    Btn->setText("Bt2");
    }

    static void updateImage(cv::Mat image, QLabel* videolb)
    {
    //conversion from Mat to QImage
    cv::Mat dest;

    cvtColor(image, dest,CV_BGR2RGB);
    QImage qimg = QImage((uchar*) dest.data, dest.cols, dest.rows, dest.step, QImage::Format_RGB888);
    
    //show Qimage using QLabel
    videolb->setPixmap(QPixmap::fromImage(qimg));
    

    }

    //horizontal layout
    int main(int argc, char* argv[])
    {
    QApplication app(argc, argv);

    QMainWindow*    mainWindow  = new QMainWindow(NULL);
    QWidget*        cwidget     = new QWidget(mainWindow);
    QVBoxLayout*    layout      = new QVBoxLayout;
    QPushButton*    button1     = new QPushButton(mainWindow);
    QPushButton*    button2     = new QPushButton(mainWindow);
    QLabel*         videolb     = new QLabel(mainWindow);
    QTimer*         timer       = new QTimer(mainWindow);
    cv::Mat         image       = cv::imread("test.jpg");
    
    button1->setText("QPushButton1");
    button2->setText("QPushButton2");
    videolb->setText("QLabel1");
    
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(videolb);
    
    mainWindow->setCentralWidget(cwidget);
    mainWindow->centralWidget()->setLayout(layout); //centralWidget() is getcentralWidget()
    mainWindow->resize(400, 300);
    
    QObject::connect(button1, &QPushButton::clicked, [=]
    {
        cout << "button1 clicked" << endl;
        button1->setText("Bt1");
    });
    
    QObject::connect(button2, &QPushButton::clicked, [=]
    {
        mySlot(button2);
    });
    
    timer->stop();
    QObject::connect(timer, &QTimer::timeout, [=]
    {
        updateImage(image, videolb);
    });
    timer->start(1000);
    
    mainWindow->show();
    
    return app.exec();
    

    }


  • Lifetime Qt Champion

    @fatalfeel hi and welcome to devnet,

    You should open your own thread and explain exactly what you issue is.

    Just dumping your code won't motivate anybody to answer. Also, please use the coding tags so your code will be readable.


Log in to reply