无法将信号连接到 main() 中的函数
Posted
技术标签:
【中文标题】无法将信号连接到 main() 中的函数【英文标题】:Unable to connect signal to a function inside main() 【发布时间】:2013-05-24 12:05:10 【问题描述】:我知道要在类中使用 Qt 的信号和槽机制,该类必须包含 Q_OBJECT
宏,但我试图在 main()
中使用信号和槽,而不使用任何类。
到目前为止,这是我的代码:
#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);
这是生成的 GUI 窗口:
从上面的代码中,退出按钮连接到quit()
,这是一个Qt函数,点击它就可以工作。分配给函数saveText()
的保存按钮配置为退出,但不退出。
请告诉我我在理解 Qt 中的信号和槽方面哪里出了问题。
【问题讨论】:
connect(&saveButton, &QPushButton::clicked, []()saveText();); // qt5.9.6 【参考方案1】:Qt4...
从 QObject 或其子类之一继承的所有类(例如, QWidget) 可以包含信号和槽。1
因此,您不能使用位于QObject
children 之外的插槽。
您可以将信号连接到派生自QObject
的类中的插槽。将您的插槽放在一个单独的 .h/.cpp 文件中的类中:
class MyClass : public QObject
Q_OBJECT
...
public slots:
void saveText();
;
根据 Qt5:New Signal Slot Syntax in Qt 5。您可以连接到这些类型的全局函数。 (感谢@thuga 的 cmets)
【讨论】:
那么为什么退出按钮可以工作?类中的quit()
函数是否继承自 QObject ?
quit()
是qApp
中的一个槽,qApp
是一个派生自QObject
的对象。
你可以在 Qt5 中做这样的事情
@MM。 Here 上面写着The new syntax can even connect to functions, not just QObjects
。也可以看this问题。
@thuga,非常感谢!希望您通过编辑我的代码来演示它来给出答案,但无论如何,这些链接很有帮助【参考方案2】:
我只是在这里举个例子。
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);
【讨论】:
【参考方案3】:QObject::connect(&saveButton, &QPushButton::clicked, []()saveText();); // qt5.9.6
或如masoud's answer中所述
QObject::connect(&saveButton, &QPushButton::clicked, saveText); // qt5.9.6
【讨论】:
这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review “这没有提供问题的答案。” - 什么问题? 您的答案很简短,应该是评论,而不是答案。请参考 *** 的指南。 @AashishJ “你的答案很短,应该是评论” - 答案很短并不意味着它应该是评论,这显然是一种尝试回答这个问题,它是否正确不是 LQP 审查队列的工作,这就是 up/downvoting 的目的。【参考方案4】:可以将信号连接到主函数内部的函数。 这已经在 Qt5.15 中进行了测试。这是一个简单的例子,QPushButton 'Clicked' 信号用于触发一个函数(这里我使用了 lamda,但也可以使用常规函数)。
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();
【讨论】:
以上是关于无法将信号连接到 main() 中的函数的主要内容,如果未能解决你的问题,请参考以下文章