C++ Qt C++;连接QPushButton单击

C++ Qt C++;连接QPushButton单击,c++,qt,qtgui,qtcore,qt-signals,C++,Qt,Qtgui,Qtcore,Qt Signals,我刚刚开始使用QtGUI进行开发,并且我已经查阅了一些教程和文档,根据我所阅读的内容,这应该是可行的 #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()->fi

我刚刚开始使用QtGUI进行开发,并且我已经查阅了一些教程和文档,根据我所阅读的内容,这应该是可行的

#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");
}
我知道我可以只做QtProject::on_TestBtn_clicked();但我希望使用连接、信号和插槽使其工作。

1)QApplication中没有
test()
插槽。您需要创建自己的类,继承QApplication,并为该类指定一个
test()
slot。您所做的只是创建一个常规函数,这没有任何帮助


2) 您没有检查connect的返回值,这意味着您没有看到它给了您一个错误,这可能会给您一些线索。

您可以将信号连接到源于
QObject
的类中的插槽,以便元编译器可以推断插槽调用。但是您的
test()
是全局函数。如Laszlo Papp所示,您必须将slot函数放入一个派生自
QObject
并支持
Q_OBJECT
宏的类中,或者定义一个lambda函数(支持C++11)

例如:

// 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();
}
//testwrapper.h
类TestWrapper:公共QObject
{
Q_对象
//...
公众时段:
无效试验();
};
//main.cpp
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
QTW项目;
w、 show();
QPushButton*lpTestBtn=w.window()->findChild(“TestBtn”);
TestWrapper-tw;
连接(lpTestBtn,信号(点击()),tw,插槽(测试());
返回a.exec();
}

代码中的测试函数不是插槽,也不属于您似乎使用过的Q(核心)应用程序类

最好是将测试函数中的这一行移动到使用lambda语法的连接。这将需要C++11支持,但这是目前非常常见的用法

你会用。这将为您将来的运行时问题省去一些麻烦,因为它们会在编译时出现

因此,您可以这样写:

main.cpp 构建并运行
还请注意,为QPushButton对象创建全局指针是个坏主意。它不仅会泄漏内存,还可能出现其他问题。

运行程序时是否会收到连接警告或类似的警告?它看起来不像“void test()”在w.window()中声明为插槽-它只是一个本地函数…
您需要创建自己的类
->您可以,但不需要。对于IMHO来说,继承QApplication是个坏主意。可能是OP误解了正在做的事情。在正常运行时场景中,人们不需要检查connect的返回值。通常只为调试而进行,尽管没有那么多,因为控制台上通常有明确的警告。1)我想知道测试槽的实现在哪里。2) 我想知道你为什么把原来的测试方法留在家里。这段代码不会编译,而且它还有一个未使用的测试函数,如果使用一个好的编译器将警告变成错误,这是另一个错误。@LaszloPapp ad 1)我建议使用testwrapper.cpp ad 2)我确信在这种情况下,您自己的大多数项目不会编译为1)so main.cpp进行声明,但是testwrapper.cpp的定义是什么?听起来很奇怪。我宁愿使用tw.h和tw.cpp,但我认为这里不需要单独的源文件。2) 我所有的项目目前都在编译,谢谢。:)您仍然有多余的
void test()不过。3) 我不知道你为什么需要在这里的类中使用
。@LaszloPapp我已经添加了代码应该放在哪里的指示into@user2920222:另外,在主窗口外创建gui元素也是个坏主意。QtProject也是主窗口的坏名称。
// 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();
}
#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();
}
TEMPLATE = app
TARGET = main
QT += widgets
CONFIG += c++11
SOURCES += main.cpp
qmake && make && ./main