QT学习笔记2

1.重载自定义信号与槽:

定义天黑类:里面有一个有参数的信号和没有参数的信号

tianhei.h

#ifndef TIANHEI_H
#define TIANHEI_H

#include 

class Tianhei : public QObject
{
    Q_OBJECT
public:
    Tianhei();  //构造函数声明

signals:
    void tianhei();
    void tianhei(QString name);  //信号只需声明

public slots:
};

#endif // TIANHEI_H

定义想你类:同样一个有参数一个没有参数

xingni.h

#ifndef XINGNI_H
#define XINGNI_H

#include 

class Xingni : public QObject
{
    Q_OBJECT
public:
    explicit Xingni(QObject *parent = nullptr);

signals:

public slots:
    void xiangni();
    void xiangni(QString name);   //槽函数
};

#endif // XINGNI_H

xingni.c

#include "xingni.h"
#include 

Xingni::Xingni(QObject *parent) : QObject(parent)
{

}

void Xingni::xiangni(){

    qDebug()<<"想你了";

}

void Xingni::xiangni(QString name){

    qDebug()<<"想你了"<

我们选择第一种按键绑定方式,即用中转函数,

点击按钮,按钮发送点击信号,MainWindow接收信号,执行heilai()函数;

heilai()函数会让hei发送tianhei信号,xing接收信号执行xingni槽函数;

但是我们发现,由于信号函数和槽函数存在两个重名的函数,一个有参数,一个没有参数,程序存在歧义,不知道执行哪一个,这时候就是指针大显身手的时候了。我们定义一个函数体指针分别接收有参数的信号函数和槽函数,把两个指针传到connect中去就好了;

mainwindow.c
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    ui->setupUi(this);

    this->setWindowTitle("love");

    //设置固定大小,设置完成不可拉伸
    this->setFixedSize(400,300);


    QPushButton *butten=new QPushButton("点我天黑",this);
    butten->move(150,100);
    //定义一个按钮实例子
    this->hei =new Tianhei();  //实例化对象,注意后面括号
    this->xing =new Xingni();


    void (Xingni::*XINGNI)(QString)=&Xingni::xiangni;
    void (Tianhei::*TIANHEI)(QString)=&Tianhei::tianhei;
//    connect(butten,&QPushButton::clicked,hei,XINGNI);
    connect(butten,&QPushButton::clicked,this,&MainWindow::heilai);
    connect(hei,TIANHEI,xing,XINGNI);


    //天黑发出天黑信号,xing接收,调用槽函数;

}


void MainWindow::heilai(){
     qDebug()<<"天要黑了!";
    emit hei->tianhei("刘亦菲");  //定义的有参数所以要传参
}



MainWindow::~MainWindow()
{
    delete ui;
}

 void (Xingni::*XINGNI)(QString)=&Xingni::xiangni;
 void (Tianhei::*TIANHEI)(QString)=&Tianhei::tianhei;

void是函数返回值,(Xingni::*XINGNI)(QString)=&Xingni::xiangni;XINGNI中是Xingni::xiangni的地址,由于前边有参数,因此会自动传有参数的函数地址。

QT学习笔记2_第1张图片 QString----->QByteArray-------->char *    去引号

qDebug()<<"想你了"<

 QT学习笔记2_第2张图片

2.信号与槽总结

(1)发送者与接收者是需要是QObjec的子类(槽函数是全局,lambda除外)

(2)信号与槽返回值都是void类型。

(3)信号只需要声明不需要定义实现,槽函数需要声明也需要实现(注意继承方式,public,private,protected)。

(4)槽函数是普通函数,会受到public,private,protected影响。

(5)使用emit在恰当的位置发送信号

(6)任何成员函数,static函数,全局函数和Lambda表达式都可以作为槽函数

(7)使用connect()函数连接信号与槽

(8)信号与槽的参数要一致,参数类型一致,槽函数参数可以比信号少,但是顺序要一直。

举例:

        signal(Qstring)和slot(Qstring)

        signal(Qstring,Qstring)和slot(Qstring)

        signal(Qstring,Qstring)和slot(Qstring,int)错误

        signal(Qstring,Qstring,int)和slot(Qstring,Qstring)

        signal(Qstring,Qstring,int)和slot(Qstring,int)  错误

(9)信号与槽可以一对一,一对多(发出信号,槽函数一个一个执行,顺序不确定)多对一(发出任意一个信号,槽函数都执行)

(10)信号可以连接信号

(11)槽可以断开连接(disconnect),槽可以被取消连接(当一个对象delete了,取消这个连接)

(12)可以使用C++11中的lambda

3.Lambda表达式

格式:[capture] (parameters) mutable -> return-type {statement}

(1)[ ]标识一个Lambda的开始,这部分必须存在,不能省略

(2)()参数列表,如果不需要传递参数的话,()可以一同省略

(3)如果使用mutable,参数列表()不能省略,即使参数为空。如果使用mutable修改拷贝,值本身不变。

(4) -> return-type返回值类型,如果不需要可以省略;

(5){statement}函数体,可以使用参数列表,也可以使用捕获列表;

1)传参Lambda

#include 
using namespace std;
int main() {
	int a = 1, b = 2;
	auto A1 = [](int x, int y)->int {return x + y; };
	cout << A1(a, b);
	return 0;
}

QT学习笔记2_第3张图片

2)捕获列表(只读)

利用捕获列表传参

#include 
using namespace std;
int main() {
	int a = 1, b = 2;
	auto A1 = [a,b]()->int {return a + b; };
	cout << A1();
	return 0;
}

此时不能修改a和b的值,因为默认传参方式是“=”,只有读权限,没有修改权限

#include 
using namespace std;
int main() {
	int a = 1, b = 2,c=3;
	auto A1 = [=]()->int {return a + b+c; };
	cout << A1();
	return 0;
}

 [=]将匿名函数范围内的所有局部变量捕获

2)捕获列表(修改)

#include 
using namespace std;
int main() {
	int a = 1, b = 2, c = 3;
	auto A1 = [&]()->int { a = 3, b = 3; return a + b + c; };
	cout << "a=" << a << endl << "b=" << b << endl << "c=" << c << endl;
	cout << A1();
	return 0;
}

[&] 引用传值,因此可以改变值,但是改变的值是copy的值,函数外的值不改变。

#include 
using namespace std;
int main() {
	int a = 1, b = 2, c = 3;
	auto A1 = [=]()mutable->int { a = 3, b = 3; return a + b + c; };
	cout << "a=" << a << endl << "b=" << b << endl << "c=" << c << endl;
	cout << A1();
	return 0;
}

QT学习笔记2_第4张图片

QT学习笔记2_第5张图片

        

QT学习笔记2_第6张图片

 4.MainWindow:提供对话框

一个菜单栏(menu bar),多个工具栏(tool bar),多个铆接部件(dock widgets)(浮动窗口),一个状态栏(status bar),一个中心部件(central widget)

QT学习笔记2_第7张图片

1)菜单栏:

        (1)菜单栏类QMenuBar:创建菜单栏

        (2)菜单类QMenu:创建菜单

        (3)QAction:充当子菜单

QMenuBar *menubar=new QMenuBar(this); //创建菜单栏两种方法
QMenuBar *menubar=menuBar();

 this->setMenuBar(menubar);  //添加到该页面中


QMenu *menu1=new QMenu("文件");  //创建菜单
menubar->addMenu(menu1)     //将menu添加到menubar菜单栏中

QAction *act1=new QAction("打开文件");  //创建子菜单
menu1->addAction(act1);     //将act1添加menu1子菜单中



#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    resize(800,600);
    ui->setupUi(this);
  //  QMenuBar *menubar=new QMenuBar(this);
    QMenuBar *menubar=menuBar();
    //创建菜单栏
    this->setMenuBar(menubar);
    //创建菜单
    QMenu *menu1=new QMenu("文件");
    QMenu *menu2=new QMenu("编辑");
    QMenu *menu3=new QMenu("构建");
    QMenu *menu4=new QMenu("调试");
    QMenu *menu5=new QMenu("Analyze");
    QMenu *menu6=new QMenu("工具");
    QMenu *menu7=new QMenu("控件");
    QMenu *menu8=new QMenu("帮助");
    menubar->addMenu(menu1);
    menubar->addMenu(menu2);
    menubar->addMenu(menu3);
    menubar->addMenu(menu4);
    menubar->addMenu(menu5);
    menubar->addMenu(menu6);
    menubar->addMenu(menu7);
    menubar->addMenu(menu8);


    QAction *act1=new QAction("新建文件");
    QAction *act2=new QAction("打开文件");
    QAction *act3=new QAction("另存为");
    QAction *act4=new QAction("关闭");
    QAction *act5=new QAction("最近访问文件");
    QAction *act6=new QAction("保存文件");
    QAction *act7=new QAction("打印");
    QAction *act8=new QAction("退出");
    menu1->addAction(act1);
    menu1->addAction(act2);
    menu1->addAction(act3);
    menu1->addAction(act4);
    menu1->addAction(act5);
    menu1->addAction(act6);
    menu1->addAction(act7);
    menu1->addAction(act8);

    connect(act1,&QAction::triggered,[=](){qDebug()<<"已新建文件";});
    connect(act2,&QAction::triggered,[=](){qDebug()<<"已打开文件";});
    connect(act3,&QAction::triggered,[=](){qDebug()<<"已另存为文件";});
    connect(act4,&QAction::triggered,this,&MainWindow::close);
    connect(act5,&QAction::triggered,[=](){qDebug()<<"最近访问文件";});
    connect(act6,&QAction::triggered,[=](){qDebug()<<"已保存文件";});
    connect(act7,&QAction::triggered,[=](){qDebug()<<"打印文件";});
    connect(act8,&QAction::triggered,[=](){qDebug()<<"退出";});
}

MainWindow::~MainWindow()
{
    delete ui;
}

QT学习笔记2_第8张图片

 这样一个简易的菜单栏就写完了

QT学习笔记2_第9张图片

 点击就会执行自己定义的函数,接下来只需要真正保存,新建文件等函数就可以了,我只写了关闭,别的用Lambda代替,实测是可以的。

你可能感兴趣的:(qt,学习,笔记)