4

I have just started developing using QtGUI and I have checked out some tutorials and documentation, and by what I've read this should work.

#define CONNECT QObject::connect

void test();
QPushButton *lpTestBtn;
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QtProject w;
   w.show();

   lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
   CONNECT(lpTestBtn, SIGNAL(clicked()),qApp,SLOT(test()));

   return a.exec();
}

void test()
{
    lpTestBtn->setText("Hi");
}

But test() never gets called. Also, lpTestBtn is not null and is found correctly.

I have tried the following changes

CONNECT(lpTestBtn, SIGNAL(clicked()),qApp->activeWindow(),SLOT(test()));

CONNECT(lpTestBtn, SIGNAL(clicked()),w.window(),SLOT(test()));

I know I can just do QtProject::on_TestBtn_clicked(); but I'd like to get it working using CONNECT,SIGNAL and SLOT.

1
  • Do you get a connection warning or anything like this when you run the program? It does not look like "void test()" is declared as a slot in w.window() - its just a local function... Commented May 24, 2014 at 13:53

3 Answers 3

4

The test function in your code is not a slot, nor does it belong to the Q(Core)Application class as you seem to have used it.

The best would be is to move that one line in the test function to the connection with the lambda syntax. This will require C++11 support, but that is in quite common use these days.

You would use the new shiny signal-slot syntax. This would spare you some headache for runtime issues in the future because they would appear at compilation-time.

Therefore, you would write something like this:

main.cpp

#include <QMainWindow>
#include <QApplication>
#include <QPushButton>

int main(int argc, char **argv)
{
   QApplication a(argc, argv);
   // Replace it with "QtProject".
   QMainWindow w;
   w.show();

   QPushButton * lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
   QObject::connect(lpTestBtn, &QPushButton::clicked, [=]() {
        lpTestBtn->setText("Hi");
   });

   return a.exec();
}

main.pro

TEMPLATE = app
TARGET = main
QT += widgets
CONFIG += c++11
SOURCES += main.cpp

Build and Run

qmake && make && ./main

Please also note that it is bad idea to create a global pointer for a QPushButton object. It not only leaks the memory, but you could have other issues, too.

Sign up to request clarification or add additional context in comments.

1 Comment

@user2920222: Also, it is a bad idea to create the gui elements outside your main window. QtProject is also bad name for the mainwindow.
2

1) QApplication doesn't have a test() slot in it. You need to make your own class, inheriting QApplication, and give that class a test() slot. What you've done is create a regular function, which won't help.

2) You didn't check the return value of connect, which means you didn't see that it was giving you an error, which would probably have given you some clues.

1 Comment

You need to make your own class -> You can, but you do not need to. Inheriting QApplication for this is a bad idea IMHO. It is probably the OP misunderstood what was being done. People do not need to check the return value of connect in normal runtime scenario. It is usually only done for debugging, although not that much even then because there is usually a clear warning on the console.
1

You can connect signals to the slots which are in classes derived from QObject so meta compiler can deduce slot calls. But your test() is global function. You have to put your slot function inside a class that derives from QObject and supports Q_OBJECT macro or define a lambda function ( with C++11 support) as Laszlo Papp showed.

Example:

// testwrapper.h
class TestWrapper : public QObject
{
   Q_OBJECT

   //...

   public slots:
     void test();

};


// main.cpp
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QtProject w;
   w.show();

   QPushButton * lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
   TestWrapper tw;
   CONNECT( lpTestBtn, SIGNAL( clicked()),tw,SLOT( test()));

   return a.exec();
}

4 Comments

1) I wonder where the implementation is for the test slot. 2) I wonder why you left the original test method in. This code would not compile, and it would also have an unused test function, which is another error if warnings are turned into errors with a good compiler.
@LaszloPapp ad 1) I suggest testwrapper.cpp ad 2) I am sure that in such case most of your own projects would not compile too
1) so main.cpp for the declaration, but testwrapper.cpp for the definition? Sounds strange. I would rather do tw.h and tw.cpp then instead, but I think there is no need for a separate source file here. 2) All my projects compile currently, thanks. :) You still have the superfluous void test(); though. 3) I am not sure why you need ... in the class here.
@LaszloPapp I have added indications where the code should be put into

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.