简体   繁体   中英

Qt C++ connect QPushButton click

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) 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.

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();
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM