一、Xmind整理:
二、上课笔记整理:
1.信号与槽
class Widget : public QWidget
{
Q_OBJECT //信号与槽的元对象
signals:
void my_signal(); //自定义信号函数
public slots:
void my_slot(); //自定义的槽函数
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
2.qt4版本的连接函数,该版本的连接是不友好的连接
[static] QMetaObject::Connection //返回值是一个连接,并且该函数是一个静态成员函数
QObject::connect( //函数名
const QObject *sender, //信号的发射者,是组件的指针
const char *signal, //要发射的信号是一个C语言风格的字符串,将信号函数传递进来时,需要使用SIGNAL宏进行转换
const QObject *receiver, //信号的接受者,是组件的指针
onst char *method) //处理信号的槽函数,是C风格字符串,将槽函数传递进来时,需要使用SLOT宏进行转换
注意:信号函数必须是信号的发射者所在的类中有的信号函数,而槽函数也必须是信号的接受者中有的槽函数
举个例子:
QLabel *label = new QLabel;
QScrollBar *scrollBar = new QScrollBar;
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
label, SLOT(setNum(int)));
3.qt5版本的连接函数
[static] QMetaObject::Connection //返回值是一个连接,并且该函数是一个静态成员函数
QObject::connect( //函数名
const QObject *sender, //信号的发射者,是组件的指针
PointerToMemberFunction signal, //信号函数的函数指针变量,直接填写函数名即可
const QObject *receiver, //信号的接受者,是组件的指针
PointerToMemberFunction method) //槽函数的函数指针变量,直接填写函数名即可
举个例子:
QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit, &QLineEdit::textChanged,
label, &QLabel::setText);
4.信号连接外部函数或lambda表达式
[static] QMetaObject::Connection //返回值是一个连接,并且该函数是一个静态成员函数
QObject::connect( //函数名
const QObject *sender, //信号的发射者,是组件的指针
PointerToMemberFunction signal, //信号函数的函数指针变量,直接填写函数名即可
Functor functor) //处理信号的功能函数,可以是全局函数,也可以是lambda表达式
举个例子:
void someFunction();
QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, someFunction);
Lambda 表达式作为槽函数:
QByteArray page = ...;
QTcpSocket *socket = new QTcpSocket;
socket->connectToHost("qt-project.org", 80);
QObject::connect(socket, &QTcpSocket::connected, [=] () {
socket->write("GET " + page + "\r\n");
});
5.断开信号与槽的连接
//断开按钮对应的槽函数
void Widget::on_btn6_clicked()
{
disconnect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));
disconnect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);
}
6.信号与槽的案例
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QDebug>
#include<QPushButton>
#include<QTextToSpeech> //文本转语音的头文件
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT //信号与槽的元对象
signals:
void my_signal(); //自定义信号函数
public slots:
void my_slot(); //自定义的槽函数
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btn2_clicked();
void on_btn6_clicked();
private:
Ui::Widget *ui;
//自定义一个按钮
QPushButton *btn3;
//定义一个播报员指针
QTextToSpeech *speecher;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
void fun()
{
qDebug()<<"我是过路的";
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//给播报员实例化空间
speecher = new QTextToSpeech(this);
//给btn3实例化空间
this->btn3 = new QPushButton("按钮3", this);
this->btn3->move(ui->btn2->x(), ui->btn2->y()+50);
this->btn3->resize(ui->btn2->size());
//使用qt4版本的连接,将按钮3发射的pressed信号与按钮1的槽函数进行连接
connect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));
//参数1:信号的发射者,按钮3的指针
//参数2:要发射的信号,是在按钮所在类中拥有的信号函数,需要使用SIGNAL宏函数进行转换
//参数3:信号的接受者,ui界面上的按钮1指针
//参数4:处理信号的槽函数,是信号接收者所在类中拥有的槽函数
//注意:该链接方式是不友好的链接,原因是 即使宏函数中写错,编译器不报错,但是没有现象
//使用qt5版本的链接,将ui界面上的btn4按钮发射的clicked信号,与当前界面的自定义的槽函数连接
connect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);
//将ui界面上的按钮5,发射的clicked信号,连接到全局函数中
connect(ui->btn5, &QPushButton::clicked, fun);
//将ui界面上的按钮5发射的clicked信号连接到lambda表达式中
connect(ui->btn5, &QPushButton::clicked, [&](){
// qDebug()<<"我是路人乙";
speecher->say("我是路人乙");
});
//将当前界面的my_signal信号连接到自定义的槽函数中
connect(this, &Widget::my_signal, [&](){
speecher->say("已经成功断开按钮3和按钮4的连接");
});
}
Widget::~Widget()
{
delete ui;
}
//自定义槽函数的实现
void Widget::my_slot()
{
static int num = 0;
if(num%2)
{
ui->btn2->setEnabled(false);
}else
{
ui->btn2->setEnabled(true);
}
num++;
}
//该函数就是按钮2的clicked信号对应的槽函数
void Widget::on_btn2_clicked()
{
static int num = 0;
if(num % 3 == 0)
{
ui->btn2->setStyleSheet("background-color:red;");
}else if(num % 3 == 1)
{
ui->btn2->setStyleSheet("background-color:yellow;");
}else
{
ui->btn2->setStyleSheet("background-color:green;");
}
num++;
}
//断开按钮对应的槽函数
void Widget::on_btn6_clicked()
{
disconnect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));
disconnect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);
//发射自定义的信号
emit my_signal();
}
7.信号函数与槽函数参数个数总结
1、信号函数和槽函数进行链接时,一般要求信号函数和槽函数的参数保持一致
connect(信号发送者, SIGNAL(signalFun()),信号接收者, SLOT(slotFun())); //Ok
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int))); //Ok
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(int, char))); /connect(信号发送者, SIGNAL(signalFun(char, int)),信号接收者, SLOT(slotFun(int, char))); //False
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(char))); //False
2、当信号函数的参数大于槽函数的参数时
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun())); //Ok
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(int))); //Ok
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(char))); //False
3、当信号函数的参数小于槽函数的参数时
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int, char))); //False
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int, char=0))); //Ok
#include <QWidget>
#include<QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals:
void my_signal(); //自定义信号函数
void my_signal_1(QString msg); //自定义带参数的信号函数
public slots:
void btn1_slot1(); //声明函数
void btn1_slot2(); //声明函数
void my_signal_1_slot(QString m = "lallalallalaal");
private slots:
void on_btn3_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//1、一个信号可以连接多个槽函数,当信号发射时,所有与之连接的槽函数全部都执行
connect(ui->btn1, &QPushButton::clicked, this, &Widget::btn1_slot1);
connect(ui->btn1, &QPushButton::clicked, this, &Widget::btn1_slot2);
//2、一个槽函数可以连接多个信号
connect(ui->btn2, &QPushButton::clicked, this, &Widget::btn1_slot1);
//3、信号函数连接信号函数,表明发射第一个信号后,第二个信号跟着发射
connect(ui->btn2, &QPushButton::clicked, this, &Widget::my_signal);
connect(this, &Widget::my_signal, [](){
qDebug()<<"德玛西亚";
});
//4、连接my_signal_1信号到自定义的槽函数中
connect(this, SIGNAL(my_signal()), this, SLOT(my_signal_1_slot()));
}
Widget::~Widget()
{
delete ui;
}
//槽函数1的定义
void Widget::btn1_slot1()
{
qDebug()<<"Good good study";
}
//槽函数2的定义
void Widget::btn1_slot2()
{
qDebug()<<"day day up";
}
//按钮3发射的信号对应的槽函数
void Widget::on_btn3_clicked()
{
qDebug()<<"我现在想发射一个my_signal_1信号";
//emit my_signal_1("hello world");
emit my_signal();
}
//定义处理my_signal_1的槽函数
void Widget::my_signal_1_slot(QString m)
{
qDebug()<<"我是处理my_signal_1信号的槽函数:"<<m;
}
8.使用信号与槽完成两个界面的跳转
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals:
void jump(); //自定义跳转函数
private slots:
void on_jumpBtn_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
/***********************************第二个界面的头文件*******************/
#ifndef SECOND_H
#define SECOND_H
#include <QWidget>
namespace Ui {
class Second;
}
class Second : public QWidget
{
Q_OBJECT
public:
explicit Second(QWidget *parent = nullptr);
~Second();
public slots:
void jump_slot(); //定义有关处理跳转信号的槽函数
private:
Ui::Second *ui;
};
#endif // SECOND_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//信号函数也可以连接信号函数
//connect(ui->jumpBtn, &QPushButton::clicked, this, &Widget::jump);
}
Widget::~Widget()
{
delete ui;
}
跳转按钮对应的槽 函数
void Widget::on_jumpBtn_clicked()
{
//发射跳转信号
emit jump();
//关闭当前 界面
this->hide();
}
/*************************************第二个文件的源文件****************/
#include "second.h"
#include "ui_second.h"
Second::Second(QWidget *parent) :
QWidget(parent),
ui(new Ui::Second)
{
ui->setupUi(this);
}
Second::~Second()
{
delete ui;
}
//处理跳转信号函数对应的槽函数
void Second::jump_slot()
{
this->show(); //将当前界面进行展示
}