Search code examples
c++qtqtimer

QTimer won't start when passing a variable


I have a QTimer object that kicks off a function every second. The timer runs correctly if I do the following

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    // Set a Qtimer to update the OSD display every 1 second
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(print()));
    timer->start(1000);
}

void MainWindow::print() 
{
    printf("hello world\n");
}

But I want to pass a variable to print(). But when I do this, I never see my print statement.

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    // Set a Qtimer to update the OSD display every 1 second
    QTimer *timer = new QTimer(this);    
    int val = 42;
    // Now pass val to print()
    connect(timer, SIGNAL(timeout()), this, SLOT(print(val)));
    timer->start(1000);
}

void MainWindow::print(int val) 
{
    // I never see my print statement
    printf("hello world, val=%d\n", val);
}

header.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();

    public slots:
        void print(int val);

Why does this not work? What can I do to pass a variable into print() using QTimer?


Solution

  • connect(timer, SIGNAL(timeout()), this, SLOT(print(val)));
    

    Qt signal/slot connections don't work that way. The text within the SIGNAL() and SLOT() macros has to be the signature of the signal/slot method, verbatim; you can't put variables or other non-method-signature text there.

    If you look at your program's stdout while it runs, you'll see an error message printed by connect() telling you that it can't find any slot-method named print(val).

    If you want to provide a separate value for your slot, you could either make val a member-variable of your class, and have print() look at the member variable instead of an argument, or you could use an intermediary slot, like this:

    public slots:
       void print(int val); 
       void print42() {print(val);}
    

    ... and then connect your signal to SLOT(print42()) instead.