我刚刚开始使用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");
}
但是test()永远不会被调用。此外,lpTestBtn不为空并且找到正确。
我尝试了以下更改
CONNECT(lpTestBtn, SIGNAL(clicked()),qApp->activeWindow(),SLOT(test()));
CONNECT(lpTestBtn, SIGNAL(clicked()),w.window(),SLOT(test()));
我知道我可以做QtProject :: on_TestBtn_clicked();但是我想使用CONNECT,SIGNAL和SLOT来使其工作。
答案 0 :(得分:2)
1)QApplication中没有test()
个插槽。您需要创建自己的类,继承QApplication,并为该类提供test()
个插槽。你所做的就是创建一个常规功能,但不会给你带来帮助。
2)你没有检查connect的返回值,这意味着你没有看到它给你一个错误,这可能会给你一些线索。
答案 1 :(得分:1)
您可以将信号连接到从QObject
派生的类中的插槽,以便元编译器可以推断出插槽调用。但是你的test()
是全局函数。你必须把你的插槽函数放在一个派生自QObject
的类中,并支持Q_OBJECT
宏或定义一个lambda函数(支持C ++ 11),如Laszlo Papp所示。
示例:
// 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();
}
答案 2 :(得分:0)
代码中的测试函数不是一个插槽,也不属于Q(Core)Application类,因为您似乎已经使用过它。
最好的方法是将测试函数中的一行移动到与lambda语法的连接。这将需要C ++ 11支持,但现在这种情况非常普遍。
您将使用the new shiny signal-slot syntax。这将使您在将来因运行时问题而烦恼,因为它们将出现在编译时。
因此,你会写这样的东西:
#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
请注意,为QPushButton对象创建全局指针是个坏主意。它不仅会泄漏内存,还会产生其他问题。