“信号/槽”(Signals & Slots) 机制是 Qt 核心之一,类似于 MFC 的消息映射机制,这个机制的作用主要是类之间传递信息,一个类发送一个“信号”(signals),另一个类接收这个“信号”称之为“槽”(slots)。
例如,上一篇文章中的例子,一个按钮(QPushButton) 一个点击事件 clicked() 称之为“信号”,接收处理这个点击事件的类中函数称之为“槽”,HelloWorld::chinese() 与 HelloWorld::english(),实际上这是普通的函数。有了“信号”与“槽”,我们需要将他们“连接”起来:connect(),这个 QObject 的静态函数,QObject 是 Qt 中所有类的基类。我们可以打开“Qt 助手”(assistant.exe),输入 signals 查询这个机制的文档:
Signals & Slots 的用法,上一篇文章已经提到了,一个 QPushButton 的点击事件,我们在 helloworld.h 文件中声明两个函数(“槽”):chinese() 与 english(),并且实现这两个函数,然后就可以“连接”这个“信号”(点击事件)与“槽”(接收函数):
connect(ui.btnChinese, SIGNAL(clicked()), this, SLOT(chinese()));
connect(ui.btnEnglish, SIGNAL(clicked()), this, SLOT(english()));
Qt5 可以使用另外一种方法“连接”:
connect(ui.btnChinese, &QPushButton::clicked, this, &HelloWorld::chinese);
connect(ui.btnEnglish, &QPushButton::clicked, this, &HelloWorld::english);
具体如下图:
通过上面两张图片,我们可以看到新的使用方法,去掉了 slots,并且不再使用 SIGNAL() 与 SLOT() 这两个宏将 signals 与 slots 包括起来,而是使用函数指针,这两种方法的区别:
-
使用 SIGNAL() 与 SLOT() 宏的话,需要保证“信号”与“槽”的参数必须一模一样的,例如:如果我们使用 clicked(bool) 这个“信号”的话,我们要保证 chinese(bool) 也是同样带有一样的参数,否则这个“信号/槽”的“连接”是无效的,带参数的“连接”是这样的:connect(ui.btnChinese, SIGNAL(clicked(bool)), this, SLOT(chinese(bool)));
-
新的方法,使用函数指针,好处是:“信号”与“槽”参数可以不一样的,而且不用在声明的地方添加 slots。
既然这个机制这么好用的话,我们可不可以自己定义 signals 呢?答案是肯定的,下面我们一起学习怎么实现自己的 signals,我们还是继续在 HelloWorld 工程里面修改。
首先右键 Form Files –> Add –> Class,然后选择 Qt5 Classes –> Qt5GuiClass,点击“Add”按钮:
然后在新弹出的界面输入类名 Test,点击 Finish,这样我们就添加一个界面类:
下面我们要实现的功能是,点击“中文”时弹出 Test 类的界面(为了节省时间,就不新增按钮了),关闭 Test 时改变标题名称。在 helloworld.h 中增加类对象指针 Test* test_;
在 helloworld.cpp 中实现 titleChanged(const QString& txt) 函数(另外不要忘记 #include “test.h”):
void HelloWorld::titleChanged(const QString& txt)
{
setWindowTitle(txt);
}
在 chinese() 函数后面增加:
if (test_ == NULL) {
test_ = new Test();
connect(test_, &Test::textChanged, this, &HelloWorld::titleChanged);
}
test_->show();
注意:在构造函数中,test_ 一定要初始化为 NULL。
在 test.h 中,我们添加“信号”:
signals:
void textChanged(const QString& txt);
重写父类 QWidget 的 closeEvent() 函数:
protected:
virtual void closeEvent(QCloseEvent* ev);
在 test.cpp 中实现 closeEvent() 代码:
void Test::closeEvent(QCloseEvent* ev)
{
emit textChanged(“This is the title”);
QWidget::closeEvent(ev);
}
编译运行,当我们点击“中文”按钮的时候,会弹出 Test 界面,关闭 Test 界面时,主界面的标题会变成:This is the title,为了节省时间,我们没有使用 tr() 包含它,从而可以实现多国语言切换。
源码:http://51ck.me/learning/qt/01_HelloWorld.rar
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/83425.html