Unable to connect signal to a function inside main()
Asked Answered
M

4

12

I am aware that to use the signals and slots mechanism of Qt inside a class, the class must include the Q_OBJECT macro, but I am attempting to use signals and slots in main(), without using any class.

Here is my code so far:

#include <QApplication>
#include <QWidget>
#include <QTextEdit>
#include <QtGui>

void saveText();

int main(int argv, char **args)
 {
    QApplication app(argv, args);
    QTextEdit textEdit;
    QPushButton saveButton("Save!");
    QPushButton exitButton("Exit!");
    QObject::connect(&exitButton,SIGNAL(clicked()),qApp,SLOT(quit()));
    QObject::connect(&saveButton,SIGNAL(clicked()),qApp,SLOT(saveText()));

    QVBoxLayout vlyt;
    vlyt.addWidget(&textEdit);
    vlyt.addWidget(&exitButton);
    vlyt.addWidget(&saveButton);

    QWidget mainWindow;
    mainWindow.setLayout(&vlyt);
    mainWindow.show();

    return app.exec();
}

void saveText()
{
    exit(0);
}

Here is the GUI window generated:

GUI window

From the above code, the exit button is connected to quit(), which is a Qt function, when clicked it works. The save button assigned to the function saveText(), is configured to exit, but does not do so.

Please tell me where I have gone wrong in understanding signals and slots in Qt.

Marketa answered 24/5, 2013 at 12:5 Comment(1)
connect(&saveButton, &QPushButton::clicked, [](){saveText();}); // qt5.9.6Hirai
D
10

Qt4...

All classes that inherit from QObject or one of its subclasses (e.g., QWidget) can contain signals and slots.1

So, you can not use slots where placed outside of QObject children.

You can connect signals to the slots which are in classes where derived from QObject. Put your slot in a class which is in a separated .h/.cpp file:

class MyClass : public QObject
{
   Q_OBJECT

   ...

   public slots:
     void saveText();

};

According to Qt5: New Signal Slot Syntax in Qt 5. You can connect to those type of global functions. (Thanks to @thuga's comments)

Duotone answered 24/5, 2013 at 12:8 Comment(5)
So why is exit button working ? Is the quit() function inside of a class inheriting from QObject ?Marketa
quit() is a slot inside qApp and qApp is an object which derived from QObject.Duotone
You can do something like this in Qt5 thoughCele
@MM. Here it says The new syntax can even connect to functions, not just QObjects. You can also see this question.Cele
@Cele , thanks a lot man !! Wish you had given an answer , by editing my code to demonstrate it , but thanks anyways , the links have been of great helpMarketa
R
4

I'll just put example here.

main.cpp:

#include <QCoreApplication>
#include <iostream>
#include <QObject>
#include "siggen.h"

void handler(int val){
  std::cout << "got signal: " << val << std::endl;
}

int main(int argc, char *argv[])
{
  SigGen siggen;
  QObject::connect(&siggen, &SigGen::sgAction, handler);
  siggen.action();

  QCoreApplication a(argc, argv);
  std::cout << "main prog start" << std::endl;

  return a.exec();
}

siggen.h:

#ifndef SIGGEN_H
#define SIGGEN_H

#include <QObject>

class SigGen : public QObject
{
  Q_OBJECT

public:
  explicit SigGen(QObject *parent = 0);
  void action(void);

signals:
  void sgAction(int value);
};

#endif // SIGGEN_H

siggen.cpp:

#include "siggen.h"

SigGen::SigGen(QObject *parent) : QObject(parent)
{}

void SigGen::action()
{
  emit sgAction(42);
}
Respect answered 6/3, 2017 at 6:42 Comment(0)
H
1
QObject::connect(&saveButton, &QPushButton::clicked, [](){saveText();});  // qt5.9.6

or as mentioned in the masoud's answer

QObject::connect(&saveButton, &QPushButton::clicked, saveText);  // qt5.9.6
Hirai answered 17/1, 2019 at 8:33 Comment(4)
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From ReviewSuccessful
"This does not provide an answer to the question." - what question ?Hirai
your answer is short it should be a comment, not an answer. please refer the guideline of StackOverflow.Successful
@AashishJ "your answer is short it should be a comment" - Just because an answer is short doesn't mean it should be a comment, this is clearly an attempt to answer the question, whether or not it is correct is not the job of the LQP review queue, that's what up/downvoting is for.Stunner
E
0

It is possible to connect a signal to function inside main function. This has been tested in Qt5.15. Here is the simple example where the QPushButton 'Clicked' signal is used to trigger a function (here I used lamda's, but regular functions can also be used).

int main(int argc, char *argv[])
{
    // Created QApplication
    QApplication a(argc, argv);
    
    // Created the splashscreen(which is QObject)
    QPixmap pixmap(":/images/Sample.png");
    QSplashScreen splash(pixmap);

    // Created the pushbutton and added to splashscreen
    QPushButton b(&splash);
    b.setGeometry(50,50, 100, 50);
    b.setText("FPS");
    
    // variable to be modified inside a lamda function
    int i = 0;
    
    // Connection for button clicked signal executes lamda function
    QObject::connect(&b, &QPushButton::clicked, 
    [i = static_cast<const int&>(i), &splash = static_cast<QSplashScreen&>(splash)]()mutable 
    {i = i+1; splash.showMessage("clicked: "+ QString::number(i));});
    
    // Adding properties and displaying the splashscreen
    splash.setGeometry(0,0, 1920, 1080);
    splash.setEnabled(true);
    splash.show();
    
    a.processEvents();  
    return a.exec();
}
Elrod answered 12/1, 2021 at 23:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.