文章目录
一、标准信号和槽
1. 准备工作
1.1 main.c
1.2 widget.cpp
2. 添加按钮
2.1 widget.h
2.2 widget.cpp
2.3 运行结果
3. 信号和槽(重点)
3.1 信号
3.2 自定义槽
3.3 widget.h
3.4 widget.cpp
3.5 运行结果
二、两个独立窗口
1. 添加新窗口
2. 自定义信号
3. 窗口关联
4. 代码和实现效果
4.1 实现过程
4.2 子窗口头文件 subwidget.h
4.3 子窗口源文件 subwidget.cpp
4.4 主窗口头文件 widget.h
4.5 主窗口源文件 widget.cpp
4.6 实现结果
由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。
提示:具体项目创建流程和注意事项见
QT 学习笔记(一)
一、标准信号和槽
1. 准备工作
- 这里需要注意在模板选择转变为 Application ,后续步骤相同
1.1 main.c
- 在执行完 Widget w; 语句后,并不会立马执行 w.show(); ,还要先执行 Widget 的构造函数。
- 因此,我们在编写程序时主程序尽量不要改动,保持如下状态即可。程序的编写在他对应的 .h 和 .cpp 文件当中即可。
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; // 执行 Widget 的构造函数 w.show(); return a.exec(); }
1.2 widget.cpp
- 后续代码的编写均在 widget.h 和 widget.cpp 当中进行。
- widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); }; #endif // WIDGET_H
- widget.cpp
#include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { } Widget::~Widget() { }
2. 添加按钮
- 如果直接在 widget.cpp 当中,进行按钮的编写操作,此时运行并不会产生按钮。
- 因为,局部变量放在栈区,执行完就释放,构造函数调用结束就没有了,再执行后面的 show 程序当中不会产生按钮。
- 因此,我们在头文件当中进行按钮的定义,在源文件当中进行按钮的调用即可。
2.1 widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPushButton> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); private: QPushButton b1; QPushButton *b2; }; #endif // WIDGET_H
2.2 widget.cpp
#include "widget.h" #include <QPushButton> Widget::Widget(QWidget *parent) : QWidget(parent) { b1.setParent(this); b1.setText("^_^"); b1.move(100,100); b2 = new QPushButton(this); b2->setText("abc"); } Widget::~Widget() { }
2.3 运行结果
此时,我们点击按钮并不会产生反应,原因是缺少 信号和槽。
3. 信号和槽(重点)
- QT 做处理是主要是借助信号和槽,其核心便在于信号和槽。
- 信号类似于短信。
- 槽函数类似于接收短信的手机。
3.1 信号
- 信号:就是一个软件模拟的中断(类似于单片机那种的)。
- 信号函数及其详解如下:
connect(&b1,&QPushButton::pressed,this,&Widget::close); // &b1:信号发出者,指针类型。 // &QPushButton::pressed:处理的信号。(&发生者的类名::信号名字) // this:信号接收者。 // &Widget::close:槽函数,信号处理函数。(&接收的类名::槽函数名字)
发出什么样的信号,需要进入头文件的帮助文档(光标放在头文件,按 f1 进入,按两下 f1 全屏)进行判断。如果在该头文件的帮助文档当中,没有发现 signals,便寻找他的父类。
3.2 自定义槽
- 自定义槽:普通函数的用法。
- 在 QT5 当中,自定义槽可以是任意的成员函数,普通全局函数,静态函数。
- 槽函数需要和信号一致(参数,返回值)。
- 由于信号没有返回值,所以槽函数一定没有返回值。
- 自定义槽函数是需要在对应头文件当中声明,在源文件当中编写槽函数的功能。
3.3 widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPushButton> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); void myslot(); private: QPushButton b1; QPushButton *b2; }; #endif // WIDGET_H
3.4 widget.cpp
#include#include "widget.h" #include <QPushButton> Widget::Widget(QWidget *parent) : QWidget(parent) { b1.setParent(this); b1.setText("close"); b1.move(100,100); b2 = new QPushButton(this); b2->setText("abc"); connect(&b1,&QPushButton::pressed,this,&Widget::close); connect(b2,&QPushButton::released,this,&Widget::myslot); connect(b2,&QPushButton::released,&b1,&QPushButton::hide); } void Widget::myslot() { b2->setText("123"); } Widget::~Widget() { }
3.5 运行结果
- 点击 close 会关闭窗口。
- 点击 abc 会产生如下变化:
二、两个独立窗口
1. 添加新窗口
2. 自定义信号
- 在头文件下 signals:
- 信号必须有 signals 关键字来声明。
- 信号没有返回值,但可以有参数。
- 信号就是函数的声明,只需声明,无需定义。
- 使用:emit mysignal();
3. 窗口关联
在主窗口头文件当中包含子窗口的头文件。
在子窗口当中自定义槽函数发生信号(emit mysignal();) ,在主窗口中对信号进行接收。
在主窗口中也需要自定义接收信号槽函数。
有自定义槽函数发生信号,就一定要有自定义才函数接收信号。
自定义槽函数要在头文件当中声明,源文件当中引用和实现,注意每个自定义槽函数的父类是什么。
4. 代码和实现效果
4.1 实现过程
4.2 子窗口头文件 subwidget.h
#ifndef SUBWIDGET_H #define SUBWIDGET_H #include <QWidget> #include <QPushButton> class subwidget : public QWidget { Q_OBJECT public: explicit subwidget(QWidget *parent = nullptr); void setslot(); //发送信号 signals: void mysignal(); public slots: private: QPushButton b; }; #endif // SUBWIDGET_H
4.3 子窗口源文件 subwidget.cpp
#include "subwidget.h" subwidget::subwidget(QWidget *parent) : QWidget(parent) { this->setWindowTitle("小弟"); b.setParent(this); b.setText("切换到主窗口"); b.move(150,150); connect(&b,&QPushButton::released,this,&subwidget::setslot); resize(400,300); } void subwidget::setslot() //发送信号 { emit mysignal(); }
4.4 主窗口头文件 widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPushButton> #include "subwidget.h" //子窗口头文件 class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); void changewin(); //改变窗口 void dealsub(); //处理子窗口信号 private: QPushButton a; subwidget w; }; #endif // WIDGET_H
4.5 主窗口源文件 widget.cpp
#include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { setWindowTitle("老大"); //this->setWindowTitle("老大"); a.setParent(this); a.setText("切换到子窗口"); a.move(150,150); //显示子窗口 //w.show(); connect(&a,&QPushButton::released,this,&Widget::changewin); //处理子窗口的信号 connect(&w,&subwidget::mysignal,this,&Widget::dealsub); //定义窗口大小 resize(400,300); } void Widget::changewin() { //子窗口显示 w.show(); //本窗口隐藏 this->hide(); } void Widget::dealsub() { //主窗口显示 this->show(); //子窗口隐藏 w.hide(); } Widget::~Widget() { }
4.6 实现结果
- 通过点击 切换到子窗口 和切换到主窗口 可以实现窗口的来回切换。