Qt学习:自定义信号和槽+lambda表达式+QMainWindow+资源文件+对话框

一.Qt学习:

1.自定义信号和槽

Ⅰ.信号

  • 自定义信号,只能写在signals下面
  • 返回值是void,只用声明,不用实现
  • 可以有参,可以重载

Ⅱ.槽

  • 早期的Qt版本必须写在public slots下面,高级版本可以写在public或全局下
  • 返回值是void,需要声明,也需要实现
  • 可以有参,也可以重载

Ⅲ.案例(教师饿,学生请客)

1 ).触发函数自动触发
1.无参
  1. 创建teacher.h和student.h文件

  2. 在teacher.h文件中创建信号

  3. signals:
        void hungry();
    
  4. 在student.h文件中创建槽

    public slots:
        void treat();
    };
    
  5. 在student.h文件中实现槽

    #include <QDebug>
    void Student::treat(){
        qDebug("我请客");
    }
    
  6. 在widge.h文件中创建teacher和student的指针,声明触发函数

    #include "teacher.h"
    #include "student.h"
    private:
        Ui::Widget *ui;		//UI界面
        Teacher * th;		//声明teacher指针
        Student * st;		//声明声明student指针
        void cleras();		//声明触发函数
    };
    
  7. ①//在widget.cpp文件中实例化teacher和student对象

    ②连接信号和槽

    ③创建出发函数

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->th = new Teacher(this);		//在widget.cpp文件中实例化teacher和student对象
    this->st = new Student(this);		//在widget.cpp文件中实例化teacher和student对象
    connect( th, &Teacher::hungry, st, &Student::treat);		连接信号和槽
    cleras();		//创建出发函数
}
void Widget::cleras(){		//触发函数
    emit th->hungry();
}
2.有参
  1. 重载student.h中的treat()函数

    public slots:
        void treat();
        void treat(QString foodName);
    };
    
  2. 重载teacher.h中的hungryt()函数

    signals:
        void hungry();
    
        void hungry(QString foodName);
    
    
  3. 重写触发函数

    void Widget::cleras(){
        emit th->hungry("宫保鸡丁");
    }
    
  4. 重载student.cpp中的treat()函数

    void Student::treat(QString foodName){
        qDebug() << "我请客,吃:"<<foodName.toUtf8().data();//将String型转换为char型
    }
    
  5. 有参函数的信号与槽连接:声明函数指针->函数地址

    void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
    void(Student:: *studentSlot)(QString) = &Student::treat;
    connect( th, teacherSignal, st, studentSlot);
    
2)按钮手动触发
  1. 定义一个按钮

    #include <QPushButton>
    QPushButton * btn = new QPushButton("下课",this);
    
  2. 实现按钮和函数的连接

    connect( btn, &QPushButton::clicked, this, &Widget::cleras);
    
  3. 构造student和teacher的指向无参地址的函数指针,按钮和信号的连接、信号与槽的连接。

    void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;
    void(Student:: *studentSlot2)(void) = &Student::treat;
    connect( btn, &QPushButton::clicked, th, teacherSignal2);//按钮和信号的连接
    connect( th, teacherSignal2, st, studentSlot2);			//信号与槽的连接
    


4. 断开连接

disconnect (zt,teacherSignal2,st,studentSlot2);

Ⅳ.拓展

  • 信号可以连接信号

  • 一个信号可以连接多个槽

  • 一个槽也可以连接多个信号

  • 信号和槽函数的参数类型,必须要一一对应

  • 信号的参数个数可以多于槽的参数个数,但槽的参数个数不可以多于信号的参数个数

  • QPushButton::clicked是Boolean型,只有一个参数,可以连接void型函数,但不能连接String型函数(参数类型不一致)

  • Qt4版本以前的信号和槽的连接方式

    • 利用Qt4信号槽,连接无参版本

      connect ( zt,SIGNAL(hungry()), st, SLOT(treat()));		
      
    • 优点:参数直观

    • 缺点:类型不做检测

      原因:底层将函数名转换为字符串

      ​ SIGNAL(“hungry”) SLOT(“treat”)

    • Qt5以上,支持Qt4的版本写法,反之不支持

2.Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:

[capture] (parameters)mutable ->return-type{
statement
}		//[函数对象参数] (操作符重载函数参数)mutable ->返回值{函数体}

Ⅰ.函数对象参数

  • [],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:

  • 空。没有使用任何函数对象参数。

  • =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。

  • &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。

  • this。函数体内可以使用Lambda所在类中的成员变量。

  • a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。

  • &a。将a按引用进行传递。

  • a, &b。将a按值进行传递,b按引用进行传递。

  • =,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。

  • &, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。

Ⅱ.操作符重载函数参数

  • 标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。

Ⅲ.可修改标示符

  • mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
  QPushButton * myBtn = new QPushButton (this);

  QPushButton * myBtn2 = new QPushButton (this);

  myBtn2->move(100,100);

  int m = 10;

 

  connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });

 

  connect(myBtn2,&QPushButton::clicked,this,[=] ()  { qDebug() << m; });

 

  qDebug() << m;

Ⅳ.函数返回值

  • ->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

Ⅴ.函数体

  • {},标识函数的实现,这部分不能省略,但函数体可以为空。

3.QMainWindow

QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个铆接部件(dock widge ts)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。
在这里插入图片描述

Ⅰ.菜单栏(一个)

  1. 创建菜单栏,并将其加入到菜单栏中

    #include <QMenuBar>
    QMenuBar * bar = menuBar();
    setMenuBar(bar);
    
  2. 向菜单栏中加入两个内容

    QMenu * fileMenu = bar->addMenu("文件");
    QMenu * editMenu = bar->addMenu("编辑");
    
  3. 向菜单栏的内容中加入下拉列表

    QAction * new1 = fileMenu->addAction("新建");
    QAction * old = fileMenu->addAction("打开");
    
  4. 菜单栏中的内容加入分割线

    fileMenu->addSeparator();
    

Ⅱ.工具栏(多个)

  1. 创建工具栏

    #include <QToolBar>
     QToolBar * toolBar = new QToolBar(this);
    
  2. 设置默认区域

    addToolBar(Qt::LeftToolBarArea,toolBar);
    
  3. 设置浮动

    toolBar->setFloatable(false);
    
  4. 设置是否可以移动

    toolBar->setMovable(false);
    
  5. 设置工具栏中属性

    toolBar->addAction(new1);
    toolBar->addAction(old);
    
  6. 设置分割线

    toolBar->addSeparator();
    
  7. 将按钮加入到工具栏中

    #include <QPushButton>
    QPushButton * btn = new QPushButton("asd", this);
    toolBar->addWidget(btn);
    

Ⅲ.状态栏(一个)

  1. 创建状态栏,并放到窗口中。

    #include <QStatusBar>
    QStatusBar * stBar = statusBar();
    setStatusBar(stBar);
    

Ⅳ.标签控件(左下角和右下角)

  1. 创建标签控件(默认显示左下角)

    #include <QLabel>
    QLabel * label = new QLabel("提示信息",this);
    stBar->addWidget(label);
    
  2. 右下角显示

    QLabel * label2 = new QLabel("右侧提示信息",this);
    stBar->addPermanentWidget(label2);
    

Ⅴ.铆接部件/浮动窗口(多个)

  1. 新建铆接部件,是指到窗口中,并指定位置

    #include <QDockWidget>
    QDockWidget * dockWidget = new QDockWidget("浮动",this);
    addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
    
  2. 设置后期停靠区域

    dockWidget->setAllowedAreas( Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
    

Ⅵ.中心部件(一个)

  1. 新建中心部件,放到窗口中

    #include <QTextEdit>
    QTextEdit * edit = new QTextEdit(this);
    setCentralWidget(edit);
    

4.资源文件

  • 新建资源文件夹,然后添加前缀,再添加文件

  • 添加的文件需要放在此次创建的大文件下,才可以被引用

  • 使用添加Qt资源 “:+ 前缀名 +文件名 ”

    ui->actionNew->setIcon(gIcon ( " : / Image/Luffy.png" ) );
    ui->actionopen->setIcon(QIcon ( " : / Image/LuffyQ.png" ) );
    

5.对话框

  • 连接ui界面的操作

    connect(ui->actionnew,&QAction::triggered,[=](){
    //        QDialog dlg(this);
    //        dlg.exec();
    
    //        qDebug()<<"模态对话框已弹出";
    
            QDialog * dlg2 = new QDialog(this);
            dlg2->resize(600,400);
            dlg2->show();
            dlg2->setAttribute(Qt::WA_DeleteOnClose);
            qDebug()<<"非模态对话框已弹出";
        });
    
  • 模态对话框(不可以操作其他窗口)

     QDialog dlg(this);		//创建窗口,new防止打开后直接关闭,将在栈上改放到堆上
    dlg.exec();				//执行
    
  • 非模态对话框(可以操作其他窗口)

    QDialog * dlg2 = new QDialog(this);	//创建窗口
    dlg2->resize(600,400);
    dlg2->show();						//展示
    dlg2->setAttribute(Qt::WA_DeleteOnClose);	//关闭后回收
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值