QT信号槽
2020-05-22 本文已影响0人
乡村小码夫
说明
该文只记录信号槽的简单用法,方便今后忘记如何使用时回看,避免浪费更多时间。就不赘述信号槽是啥了。
前提:创建widget项目,在此项目中实践

在“名称”处输入当前项目的名字,这样能够方便多项目之间根据名字进行管理。然后在“创建路径”处选择或者输入项目存放的路径。如果勾选“设为默认项目路径”,那么在创建下一个项目的时候就不需要再选择路径了。

默认使用“qmake”进行编译,所以直接“下一步”就好。

这里“Base class”的默认选项是“QMainWindow”,我选择了“QWidget”。它俩之间的区别在于QMainWindow多了一些组件,为了显示简洁,所以使用QWidget。然后“下一步”。

这边就是选择通过哪种编译器进行编译,这个在安装的时候会有选择,我一般选择MinGW。选择MSVC的也是可以的。然后“下一步”。

接着就是提示是否需要加入版本控制,作为测试的话,就没有必要了。生产环境可以考虑配置一下git环境,或者自己手动对项目进行版本控制。养成一个良好的习惯,避免发生一些令人懊悔的事情。

一切顺利的话,就能看到如此简洁的项目了。此时直接编译运行的话,将会得到一个什么都没有的Wdiget。
使用:添加按钮以及子页面


从左侧的组件中选中“PushButton”并拖动到中间“页面”的合适位置,然后松开鼠标。再双击,修改其显示内容为“跳转到子页面”。

点击最左侧栏的“编辑”,进入到项目列表中。在当前项目上“右击”,选中“Add New...”。

从左向右,依次选择“Qt”--“Qt 设计师界面类”。然后选中“Choose...”进行下一步操作。

默认就是“Widget”窗口,直接“下一步”就好。

将这边的“Form”类名,修改成自己喜欢的,默认也行。我这边修改为“childWidget”,最好首字母大写,这边有点尴尬...

到这边的“项目管理”,添加到项目这一项就默认好了。至于版本控制,生产环境还是建议配置。然后点击“完成”。

创建好以后,项目会直接跳转到新建类的“ui设计界面”,同样拖一个“PushButton”到界面上,并修改显示内容为“跳转到主窗口”。

切换到“编辑”,选中“widget.h”。
首先包含头文件:
#include "childwidget.h"
然后在“private:”下面创建一个类指针:
childWidget *m_pChildWidget;
image24f8d0db1d66cbfa.png
切换到“widget.cpp",实例化一个对象。
m_pChildWidget = new childWidget();
信号槽的使用
使用自带的链接

切换到“widget.ui”,选中“跳转到子页面”并“右击”。选择“转到槽...”。

这边会有很多“槽”函数可以选择,一般选择“clicked()”。今后可以根据不同需求进行选择。点击“OK”。

项目会自动跳转到该“槽”。只要在这里添上需要执行的代码,那么当按钮被“点击”时就会触发这段代码。

在其中加入
this->hide(); // 意思是隐藏当前主窗口
m_pChildWidget->show(); // 将子页面显示出来
使用connect进行信号槽操作。
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
- const QObject *sender: 信号的发送者
- const char *signal: 被发送的信号
- const QObject *receiver: 信号的接受者
- const char *method: 对应的槽函数
简单的说就是,信号的发送者告诉接受者当你收到某信号时,你就该干指定的活了。

在“widget.ui”界面上再添加一个按钮,修改为“退出”。同时在右下方的“属性”栏中,将“objectName”修改为“btnQuit”。这个修改主要是为了将来控件比较多时,能够准确的定位到想要的控件。

在“widget.h”中添加槽函数,即接收到信号后需要处理的内容。
void quitWidget();
将光标放在“quitWidget();”上,同时按下“ALT”和“ENTER”键,选择“在widget.cpp添加定义”。

随即,项目会跳转到“widget.cpp”,在其中输入
this->close();
不能忘记connect进行连接。
connect(ui->btnQuit, &QPushButton::clicked, this, &Widget::quitWidget);
这种槽函数比较简单的,完全可以用Lamda表达式的方式来完成。
以上都是老大(主窗体)对子窗体或者控件的操作,类似大哥给小弟一个命令,小弟屁颠屁颠去完成一样,没有任何商议的成分,让你干就得干。不过,如果反过来,小弟(子页面)想让大哥干活(切换到主窗口),就不能直愣愣的通知了。只能说是,小弟先发送一个信号给大哥,至于大哥愿不愿意处理,活怎么处理都无法直接干预。

将“childWidget.ui”中的按钮添加一个信号槽,可以用“右击”--“转到槽...”的方式,或者connect的方式。前一种比较方面,就使用前一种。然后,在“childWidget.h”中添加一个“信号”:
signals:
void jumpToWidget();

在上述创建的槽函数中(如多是第一种方式创建,即void childWidget::on_pushButton_clicked()中)输入:
emit jumpToWidget(); // 发送jumpToWidget()的信号
到此,小弟给大哥的信号是完成了,大哥该怎么处理呢?用connect来处理吧!

首先,在“widget.h”中创建一个需要处理“jumpToWidget()”信号的槽函数,并在“widget.cpp”中添加定义(与上面那个一致)。在其中输入:
this->show();
m_pChildWidget->hide();
不能忘记connect
connect(m_pChildWidget, &childWidget::jumpToWidget, this, &Widget::dealwithJumpToWidget);
总结
信号槽主要弄清“谁发送”,“发送的是啥信号”,“谁接收”,“接收到信号后怎么处理”这四个点就没有问题了。当然,得认清谁是大哥,谁是小弟。