QT开发学习<1>:创建第一个QT工程

1.创建工程

        1.1 点击创建项目后,选择项目路径以及 给项目起名

        1.2 项目名称不能有中文、空格

        1.3 路径不能有中文

2.创建默认窗口

        2.1 默认创建有窗口类,mywidget, 基类有三种选择:QWidget/ QMainWindow/QDialog

QWidget 是另外两个的基类

3.界面基础内容

#include "mywidget.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);//应用程序对象,qt中有且仅有一个QApplication对象

    myWidget w; //窗口对象

    w.show();  //显示窗口,默认情况下myWidget窗口对象不会自动显示,必须使用show方法

    return a.exec(); //阻塞程序,让应用程序对象进入消息循环
}

4.快捷键

        注释:ctrl + /

        运行: ctrl + r

        查找: ctrl + f

        整行移动: ctrl + shift + ↑或↓

        帮助文档: F1 退出帮助文档 :ESC

        自动对齐:ctrl + i

5.button控件

#include "mywidget.h"
#include 

myWidget::myWidget(QWidget *parent): QWidget(parent)
{
    //第一种创建btn的方法
    QPushButton *btn1 = new QPushButton;
    btn1->show();//show默认以顶层方式弹出窗口(即与当前窗口分离)
    btn1->setParent(this);//指定当前btn的父级,(将btn放在当前myWidget窗口内显示)
    btn1->setText("first button");
    btn1->move(0,0);//移动btn

    //第二种方法,QPushbutton类的构造函数有三种重载方法
    QPushButton *btn2 = new QPushButton("second button", this);
    btn2->move(100,100);

    //重置窗口大小
    resize(600,400);

    //设置固定窗口大小,设置后用户无法改变窗口大小
    setFixedSize(600,400);



}

myWidget::~myWidget()
{
}

        QT开发学习<1>:创建第一个QT工程_第1张图片

注意: QT中可以大胆的在堆中创建对象,系统会以对象树的形式帮你自动释放内存,不存在内存泄漏的问题;

6.QT中的坐标系

        窗口左上角为(0,0),X向右增加,Y向下增加,嵌套窗口以其父窗口坐标系为参考系

QT开发学习<1>:创建第一个QT工程_第2张图片

7.信号与槽

        1. 连接函数: connect

         2.connect 的四个参数:              

                                参数1:信号的发出者

                                参数2:发出的信号(函数地址

                                参数3:信号的接收者

                                参数4:处理的槽函数(函数地址

        3.信号与槽的特点:松散耦合,信号的发出者和信号的接收者原本没有任何关系,通过信号与槽机制(connect)进行耦合

#include "mywidget.h"
#include 

myWidget::myWidget(QWidget *parent): QWidget(parent)
{
    //第一种创建btn的方法
    QPushButton *btn1 = new QPushButton;
    btn1->show();//show默认以顶层方式弹出窗口(即与当前窗口分离)
    btn1->setParent(this);//指定当前btn的父级,(将btn放在当前myWidget窗口内显示)
    btn1->setText("first button");
    btn1->move(0,0);//移动btn

    //第二种方法,QPushbutton类的构造函数有三种重载方法
    QPushButton *btn2 = new QPushButton("second button", this);
    btn2->move(100,100);

    //重置窗口大小
    resize(600,400);

    //设置固定窗口大小,设置后用户无法改变窗口大小
    setFixedSize(600,400);

    //信号与槽,实现点击btn1按钮关闭myWidget窗口
    connect(btn1, &QPushButton::clicked,this, &myWidget::close);


}

myWidget::~myWidget()
{
}

        QT开发学习<1>:创建第一个QT工程_第3张图片

 8.自定义信号和槽函数

目的:不使用系统自带的信号和槽函数,自己定义一个适用于某种特殊情况下的信号和槽函数

业务:当下课铃响起时,学生通知老师下课了,老师布置家庭作业

实现:先创建两个类,class Teacher 、class Student

//Student.h文件
#ifndef STUDENT_H
#define STUDENT_H

#include 

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

signals:
       void class_is_over();//信号函数
};

#endif // STUDENT_H

        

//Teacher.h文件
#ifndef TEACHER_H
#define TEACHER_H

#include 

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);
    
    void homeWork(); //槽函数

signals:

};

#endif // TEACHER_H
//student.cpp文件,信号函数不需要具体实现
#include "student.h"

Student::Student(QObject *parent) : QObject(parent)
{

}
//teacher.cpp 槽函数需要具体实现
#include "teacher.h"
#include "QDebug"

Teacher::Teacher(QObject *parent) : QObject(parent)
{

}

void Teacher::homeWork(){

    qDebug() << "家庭作业是:背诵课后古诗三首,明天早上来了检查";
}
//myWidget.h 声明一些函数和一些变量
#ifndef WIDGET_H
#define WIDGET_H

#include 
#include "QDebug"
#include "student.h"
#include "teacher.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void bellRings();//声明触发信号的函数

private:
    Ui::Widget *ui;
    Teacher *ts;
    Student *ss;
};
#endif // WIDGET_H
//widget.cpp 具体实现自定义信号与槽的绑定
#include "widget.h"
#include "ui_widget.h"


//业务功能:下课铃响起时,学生向老师发出放学信号,老师布置家庭作业
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->ss = new Student;
    this->ts = new Teacher;

    //连接信号与槽
    connect(ss, &Student::class_is_over, ts, &Teacher::homeWork);

    bellRings();
}

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

void Widget::bellRings(){
     qDebug()<<"下课铃声响了";
     emit ss->class_is_over(); // emit 关键字,用于将ss->class_is_over函数设定为信号函数;
}

注意事项:

        自定义信号函数

               写在signals下,返回值为void,声明后不需要实现,可以有参数,可以重载

        自定义槽函数

                写在public或private下都行,返回值为void,声明后需要在.cpp中实现,可以有参数,可以重载

8.自定义信号和槽函数重载后,发生冲突

        当信号函数或者槽函数重载后,如果不给确定的信号函数和槽函数地址,编译器仅靠函数名是无法分辨该绑定哪个函数,会报错;解决办法是,使用函数指针,指向重载的函数,使用函数指针作为connect函数的参数;

注意:

        1.一个信号可以连接多个槽;

        2.多个信号可以连接同一个槽

        3.信号的参数个数可以多于槽函数的参数个数

        3.信号和槽函数的参数个数一致时,类型要一一对应

        4.信号可以连接另外一个信号;

        5.信号和槽使用disconnect断开连接

 

#include "widget.h"
#include "ui_widget.h"


//业务功能:下课铃响起时,学生向老师发出放学信号,老师布置家庭作业
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->ss = new Student;
    this->ts = new Teacher;
    
    //定义函数指针,分别指向有参的重载函数
    void (Teacher:: *p)(QString) = &Teacher::homeWork;
    void (Student:: *m)(QString)= &Student::class_is_over;

    //将函数指针作为connect函数的参数
    connect(ss, m, ts,p);//连接信号与槽

    bellRings();
}

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

void Widget::bellRings(){
     qDebug()<<"下课铃声响了";
     emit ss->class_is_over("语文"); //emit 关键字,用于将ss->class_is_over函数设定为信号函数;
}
//teacher类中重载了homework函数
class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);
    void homeWork();
    void homeWork(QString subject);

signals:

};


//student类中重载了class_is_over函数
class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

signals:
       void class_is_over();
       void class_is_over(QString b);
};


9.qt中lambda表达式的使用

        1.lambda表达式简介

以下内容摘抄自奥修的灵魂的博客lambda表达式详解

                lambda表达式又叫做Lambda函数、匿名函数, C ++标准官网展示了一个简单的lambda 表示式实例:

#include 
#include 

void abssort(float* x, unsigned n) {
    std::sort(x, x + n,
        // Lambda expression begins
        [](float a, float b) {
            return (std::abs(a) < std::abs(b));
        } // end of lambda expression
    );
}

在上面的实例中std::sort函数第三个参数应该是传递一个排序规则的函数,但是这个实例中直接将排序函数的实现写在应该传递函数的位置,省去了定义排序函数的过程,对于这种不需要复用,且短小的函数,直接传递函数体可以增加代码的可读性。

在这里插入图片描述

 

auto function = [] (int first, int second){
    return first + second;
};
	
function(100, 200);

[]标识符,捕获列表,可以使用

                       =(值传递,捕获作用域内所有的变量)、

                        &(引用传递,捕获作用域内所有变量)、

                        a(a代表作用域内的某个具体的变量)、

                        &a;

()参数

  { }  实现体

  -> 返回值类型

int a(5),b(6);
int ret = []()->int{ returen a+b; }

  mutable 修饰值传递变量,可以修改变量的拷贝值,不能修改本身

你可能感兴趣的:(qt,学习,开发语言)