Qt学习第1天:基本操作(信号与槽等) 【笔记】

文章目录

  • 1.Qt程序基本框架
        • 创建项目
        • 项目结构
        • Qt基本模块
  • 2.第一个QT程序
        • 指定父对象
        • 移动按钮位置
        • 指针按钮
  • 3. 标准信号和槽
        • 标准信号和槽
        • 自定义槽
  • 4. 两个独立的窗口
        • 自定义信号
        • 带参数的信号
        • Lamda表达式和再说信号的功能
  • 5. 坐标系统
  • 6. 内存回收机制
  • 7. 创建一个MainWindow
        • 菜单栏-工具栏
        • 状态栏
        • 核心控件和浮动窗口
        • 对话框
            • 模态和非模态对话框
            • 标准对话框和文件对话框

1.Qt程序基本框架

创建项目

选择文件路径,编辑项目名称
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第1张图片
选择编译器
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第2张图片
选择基类,并修改继承类类名
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第3张图片

项目结构

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第4张图片

  • *.pro:项目配置文件

    注意,项目配置文件中,使用#完成注释

    # 模块
    QT       += core gui
    
    # 高于4版本,添加QT += widgets,为了兼容Qt4
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    # 应用程序的名字
    TARGET = 01day_qtTest
    
    # 指定makefile的类型,app,此外还有lib等类型
    TEMPLATE = app
    
    DEFINES += QT_DEPRECATED_WARNINGS
    
    CONFIG += c++11
    
    # 源文件
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    # 头文件
    HEADERS += \
            mainwindow.h
    # UI文件
    FORMS += \
            mainwindow.ui
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    

模块的添加,选中类名,按F1进入帮助文件查看类所述模块名称,并添加到配置文件。Qt学习第1天:基本操作(信号与槽等) 【笔记】_第5张图片

Qt基本模块

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第6张图片

  • Qt Widgets:GUI最常用
  • Qt Webkit:浏览器引擎
  • Qt Test:测试单元
  • Qt SQL:数据库
  • Qt Quick、Qt QML、Qt Quick Controls、Qt Quick Dialogs:另外一个框架,主要用js实现
  • Qt Mulitmedia Widgets、Qt Mulitmedia:多媒体
  • Qt Network:网络
  • Qt GUI、Qt Core:最基本的

2.第一个QT程序

创建一个空程序
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第7张图片
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第8张图片
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第9张图片
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第10张图片
main.cpp

#include 
#include  //窗口控件基类
#include //按钮基类

int main(int argc,char **argv)
{
    QApplication app(argc,argv);

    QWidget w;
    w.show(); // 注意要人工显示才能显示
    w.setWindowTitle("CSDN 牛B!"); //窗口标题

    QPushButton b;
    b.setText("我是按钮~"); //设置按钮内容
    b.show();

    app.exec();
    return 0;
}

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第11张图片

注意:创建控件后默认是隐藏的,需要人为显示!

指定父对象

① 如果不指定父对象,对象和对象(窗口和窗口)之间没有关系,是独立的!!!
② b指定a为它的父对象,相当于把b放在a的上面

指定父对象的2种方式:

  1. setParent
  2. 通过构造函数传参

指定父对象后,只需要父对象show,上面的子对象即可自动显示。

方式1:

#include 
#include  //窗口控件基类
#include //按钮基类

int main(int argc,char **argv)
{
    QApplication app(argc,argv);

    QWidget w;

    w.setWindowTitle(QString("CSDN 牛B!")); //窗口标题

    QPushButton b;
    b.setText("我是按钮~"); //设置按钮内容
    b.setParent(&w);

    w.show(); // 注意要人工显示才能显示

    app.exec();
    return 0;
}

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第12张图片

移动按钮位置

#include 
#include  //窗口控件基类
#include //按钮基类

int main(int argc,char **argv)
{
    QApplication app(argc,argv);

    QWidget w;

    w.setWindowTitle(QString("CSDN 牛B!")); //窗口标题

    QPushButton b;
    b.setText("我是按钮~"); //设置按钮内容
    b.setParent(&w);//指定父对象
    b.move(100,100);//移动坐标

    w.show(); // 注意要人工显示才能显示

    app.exec();
    return 0;
}

左上角为坐标0点,左右为x轴,上下为y轴,以像素为单位。

方式2:

#include 
#include  //窗口控件基类
#include //按钮基类

int main(int argc,char **argv)
{
    QApplication app(argc,argv);

    QWidget w;

    w.setWindowTitle(QString("CSDN 牛B!")); //窗口标题

    QPushButton b;
    b.setText("我是按钮~"); //设置按钮内容
    b.setParent(&w);//指定父对象
    b.move(100,100);//移动坐标

    QPushButton b1(&w);//通过构造函数传参指定父对象
    b1.setText("我是传参指定父类的按钮~");

    w.show(); // 注意要人工显示才能显示

    app.exec();
    return 0;
}

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第13张图片

指针按钮

新建项目,基于Qwidget
mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include 
#include 

class mainWidget : public QWidget
{
    Q_OBJECT

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();
private:
    QPushButton b1;
    QPushButton *b2;
};

#endif // MAINWIDGET_H

main()

#include "mainwidget.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    mainWidget w;//执行MainWidget的构造函数
    w.show();

    return a.exec();
}

mainwidget.cpp

#include "mainwidget.h"
#include 

mainWidget::mainWidget(QWidget *parent)
    : QWidget(parent)
{
    //QPushButton b;
    b1.setParent(this);
    b1.setText("^_^");
    b1.move(100,100);

    b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存
    b2->setText("我是指针按钮");
}

mainWidget::~mainWidget()
{

}

3. 标准信号和槽

到目前为止,虽然创建了按钮,但是点击按钮无反应,这就需要信号和槽~

QT的核心在信号和槽,它是QT对象通信的接口!

标准信号和槽

#include "mainwidget.h"
#include 

mainWidget::mainWidget(QWidget *parent)
    : QWidget(parent)
{
    //QPushButton b;
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存
    b2->setText("我是指针按钮");

    //槽函数不需要在类的头文件中声明
        connect(&b1,&QPushButton::pressed,this,&mainWidget::close);
    /* &b1:信号发出者,指针类型
     * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字
     * this:信号接收者
     * &mainWidget::close  槽函数,信号处理函数 &接收的类名::槽函数名
    */
}

mainWidget::~mainWidget()
{

}

自定义槽

注意,如果项目编译不是想要的结果,检查一下编译的是不是当前项目,尤其是多个项目并存的时候!

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include 
#include 

class mainWidget : public QWidget
{
    Q_OBJECT

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();

    void mySlot();//自定义槽函数
private:
    QPushButton b1;
    QPushButton *b2;
};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"
#include 

mainWidget::mainWidget(QWidget *parent)
    : QWidget(parent)
{
    //QPushButton b;
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存
    b2->setText("我是指针按钮");

    connect(&b1,&QPushButton::pressed,this,&mainWidget::close);
    /* &b1:信号发出者,指针类型
     * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字
     * this:信号接收者
     * &mainWidget::close  槽函数,信号处理函数 &接收的类名::槽函数名
     */

    /* 自定义槽,普通函数的用法
     * Qt5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号都是没有返回值,所以槽函数一定没有返回值
     */
    connect(b2,&QPushButton::released,this,&mainWidget::mySlot);
    connect(b2,&QPushButton::released,&b1,&QPushButton::hide);//b2变身的同时,隐藏b1按钮
}

void mainWidget::mySlot()
{
    b2->setText("变身!");
}

mainWidget::~mainWidget()
{

}

4. 两个独立的窗口

新建一个类subwidget

subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include 
#include 


class subWidget : public QWidget
{
    Q_OBJECT
public:
    explicit subWidget(QWidget *parent = nullptr);

signals:

public slots:
private:
    QPushButton b;
};

#endif // SUBWIDGET_H

subwidget.cpp

#include "subwidget.h"

subWidget::subWidget(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("子窗口");
    b.setParent(this);
    b.setText("切换到主窗口");
    b.move(100,100);
}

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include 
#include 
#include "subwidget.h"

class mainWidget : public QWidget
{
    Q_OBJECT

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();

    void mySlot();//自定义槽函数
private:
    QPushButton b1;
    QPushButton *b2;
    QPushButton b3;

    subWidget w;
};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"
#include 

mainWidget::mainWidget(QWidget *parent)
    : QWidget(parent)
{
    //QPushButton b;
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存
    b2->setText("我是指针按钮");

    connect(&b1,&QPushButton::pressed,this,&mainWidget::close);
    /* &b1:信号发出者,指针类型
     * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字
     * this:信号接收者
     * &mainWidget::close  槽函数,信号处理函数 &接收的类名::槽函数名
     */

    /* 自定义槽,普通函数的用法
     * Qt5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号都是没有返回值,所以槽函数一定没有返回值
     */
    connect(b2,&QPushButton::released,this,&mainWidget::mySlot);
    connect(b2,&QPushButton::released,&b1,&QPushButton::hide);//b2变身的同时,隐藏b1按钮

    b3.setParent(this);
    b3.move(300,100);
    b3.setText("切换到子窗口");

    w.show();
}

void mainWidget::mySlot()
{
    b2->setText("变身!");
}

mainWidget::~mainWidget()
{

}

main.cpp

#include "mainwidget.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    mainWidget w;//执行MainWidget的构造函数
    w.show();

    return a.exec();
}

自定义信号

subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include 
#include 


class subWidget : public QWidget
{
    Q_OBJECT
public:
    explicit subWidget(QWidget *parent = nullptr);

    void sendSlot();

signals:
    /* 信号由signals关键字声明
     * 信号没有返回值,但可有参数
     * 信号就是函数的声明,只需声明,无需定义
     * 使用:emit mySignal();
     */
    void mySignal();

public slots:
private:
    QPushButton b;
};

#endif // SUBWIDGET_H

subwidget.cpp

#include "subwidget.h"

subWidget::subWidget(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("子窗口");
    b.setParent(this);
    b.setText("切换到主窗口");
    b.move(100,100);
    resize(400,300);//设置窗口大小

    connect(&b,&QPushButton::clicked,this,&subWidget::sendSlot);
}

void subWidget::sendSlot()
{
    emit mySignal();
}

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include 
#include 
#include "subwidget.h"

class mainWidget : public QWidget
{
    Q_OBJECT

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();

    void mySlot();//自定义槽函数
    void changeWidget();//
    void dealSub();
private:
    QPushButton b1;
    QPushButton *b2;
    QPushButton b3;

    subWidget sub;


};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"
#include 

mainWidget::mainWidget(QWidget *parent)
    : QWidget(parent)
{
    //QPushButton b;
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存
    b2->setText("我是指针按钮");

    connect(&b1,&QPushButton::pressed,this,&mainWidget::close);
    /* &b1:信号发出者,指针类型
     * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字
     * this:信号接收者
     * &mainWidget::close  槽函数,信号处理函数 &接收的类名::槽函数名
     */

    /* 自定义槽,普通函数的用法
     * Qt5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号都是没有返回值,所以槽函数一定没有返回值
     */
    connect(b2,&QPushButton::released,this,&mainWidget::mySlot);
    connect(b2,&QPushButton::released,&b1,&QPushButton::hide);//b2变身的同时,隐藏b1按钮

    b3.setParent(this);
    b3.move(300,100);
    b3.setText("切换到子窗口");

    //sub.show();//显示子窗口
    connect(&b3,&QPushButton::released,this,&mainWidget::changeWidget);
    //处理子窗口的信号
    connect(&sub,&subWidget::mySignal,this,&mainWidget::dealSub);
    resize(400,300);//设置窗口大小
}

void mainWidget::mySlot()
{
    b2->setText("变身!");
}

void mainWidget::changeWidget()
{
    //子窗口显示
    //本窗口隐藏
    sub.show();
    this->hide();
}

void mainWidget::dealSub()
{
    sub.hide();
    this->show();
}

mainWidget::~mainWidget()
{

}

不同窗口之间信号的通信:
① 子窗口类中定义信号,使用signals关键字定义信号函数void mySignal(),信号没有返回值,但可有参数,信号就是函数的声明,只需声明,无需定义;
② 定义信号发送函数void sendSlot(),使用connect连接控件与信号发送之间的关系:connect(&控件对象,&信号类型,this,&信号发送函数;
信号发送函数定义为:

void subWidget::sendSlot()
{
    emit mySignal();
}

使用emit来关联信号类型
③主窗口中定义信号接收函数void dealSub(),并使用connect将子窗口的信号与操作关联起来,connect(&子窗口类对象,&子窗口中定义的信号,this,&处理子窗口信号的具体操作函数);

带参数的信号

信号可以重载
subwidget.h

signals:
    /* 信号由signals关键字声明
     * 信号没有返回值,但可有参数
     * 信号就是函数的声明,只需声明,无需定义
     * 使用:emit mySignal();
     * 信号可以重载
     */
    void mySignal();
    void mySignal(int,QString);

subwidget.cpp

void subWidget::sendSlot()
{
    emit mySignal();
    emit mySignal(250,"我是子窗口");
}

注意注意:信号重载后,链接函数connect会出现二义性,这时候需要用函数指针来处理!
mainwidget.cpp

    //处理子窗口的信号
    void (subWidget::*funSignal)() = &subWidget::mySignal;
    connect(&sub,funSignal,this,&mainWidget::dealSub);
    void (subWidget::*testSignal)(int,QString) = &subWidget::mySignal;
    connect(&sub,testSignal,this,&mainWidget::dealSlot);





void mainWidget::dealSlot(int a, QString str)
{
    // str.toUtf8() -> 字节数组QByteArray
    // ……data() -> QByteArray -> char *
    qDebug() << a << str.toUtf8().data();
}

另外一种简单方法:

  • 但是注意,只要是简单方法,都可能容易出问题!

  • SIGNAL SLOT 将函数名称直接转换为字符串,而不进行错误检查

在Qt4中,可以这样写:
mainwidget.cpp

    //Qt4信号连接
    //Qt4槽函数必须有slots关键字
    connect(&sub,SIGNAL(mySignal()),this,SLOT(dealSub()));
    connect(&sub,SIGNAL(mySignal(int,QString)),
            this,SLOT(dealSlot(int,QString)));

mainwidget.h

class mainWidget : public QWidget
{
    Q_OBJECT

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();
/////////////////////////////////////
public slots:
    void mySlot();//自定义槽函数
    void changeWidget();//
    void dealSub();
    void dealSlot(int,QString);
/////////////////////////////////////
private:
    QPushButton b1;
    QPushButton *b2;
    QPushButton b3;

    subWidget sub;
};

大型项目中建议使用QT5中的语法!

Lamda表达式和再说信号的功能

C++增加的新特性,项目文件中添加CONFIG += C++11,Qt配合信号一起使用非常方便。

mainwidget.cpp中


    //Lambda表达式,匿名函数对象
    //C++11增加的新特性,项目文件:CONFIG += c++11
    //Qt配合信号一起使用,非常方便
    QPushButton *b4 = new QPushButton(this);
    b4->setText("Lambda表达式");
    b4->move(200,200);

    connect(b4,&QPushButton::released,
            [b4]()//方括号[]是用来传参的
            {
                b4->setText("123");
                qDebug() << "111111";
            }
            );

如果这样写,[=](),这会把外部所有局部变量、类中所有成员以值传递方式传递进来,此时是不能修改变量值的。

    int a=10,b=20;
    connect(b4,&QPushButton::released,
            // = :把外部所有局部变量、类中所有成员以值传递方式传递进来
            [=]()//方括号[]是用来传参的
            {
                b4->setText("123");
                qDebug() << "111111";
                qDebug() << a << b;

            }
            );

如果想修改值的大小,这样写:

    int a=10,b=20;
    connect(b4,&QPushButton::released,
            // = 把外部所有局部变量、类中所有成员以值传递方式传递进来
            //this 把类中所有成员以值传递方式传进来
            // & 把外部所有局部变量,引用方式,使用引用时,对象不能用指针类型
            [=]() mutable//方括号[]是用来传参的
            {
                b4->setText("123");
                qDebug() << "111111";
                qDebug() << a << b;
                a = 11;

            }
            );

错误示范:使用引用方式传参,传指针对象时

    connect(b4,&QPushButton::released,
            // = 把外部所有局部变量、类中所有成员以值传递方式传递进来
            //this 把类中所有成员以值传递方式传进来
            // & 把外部所有局部变量,引用方式,使用引用时,对象不能用指针类型
            [&]() mutable//方括号[]是用来传参的
            {
                b4->setText("123");//问题在这儿
                qDebug() << "111111";
                qDebug() << a << b;
                a = 11;

            }
            );

D:\Program Files (x86)\SogouInput\Components
12:42:09: The program has unexpectedly finished.
12:42:09: The process was ended forcefully.
12:42:09: G:/xxxx/qtProjects/build-01day_03_SignalAndSlot-Desktop_Qt_5_12_1_MinGW_64_bit-Debug/debug/01day_03_SignalAndSlot.exe crashed.

窗口直接崩掉

b4->setText("123");屏蔽掉:
Qt学习第1天:基本操作(信号与槽等) 【笔记】_第14张图片

此处不知道问题出在哪儿,有了解的大佬还请留言指教!

小结:最安全的方法还是[=]()这种

    connect(b4,&QPushButton::clicked,

            [=](bool isCheck)
            {
                qDebug() << isCheck;

            }
            );

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第15张图片

5. 坐标系统

#include "mywidget.h"
#include 

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    /* 对于父窗口,坐标系相对于屏幕
     * 原点:相对于屏幕左上角
     * x:往右递增
     * y:往下递增
     */
    move(750,300);

    QPushButton *b1 = new QPushButton(this);
    b1->setText("^_^");

    /* 对于子窗口,坐标系相对于父窗口
     * 原点:相对于父窗口左上角
     * x:往右递增
     * y:往下递增
     */
    b1->move(0,0);
    b1->resize(200,200);//设置按钮大小

    QPushButton *b2 = new QPushButton(b1);
    /* 对于子控件,坐标系相对于父控件
     * 原点:相对于父控件左上角
     * x:往右递增
     * y:往下递增
     */
    b2->move(50,50);
    b2->setText("@_@");

}

MyWidget::~MyWidget()
{

}

简单一句话:左上角为0点,x正为→,y正为↓

6. 内存回收机制

动态分配空间,如果不做处理,可能会造成内存泄露的问题。Qt中自动实现内存回收,但有两个条件:①指定父对象后;②直接或间接继承与QObject这时,如果子对象是动态分配空间(new),不需要手动释放(delete),系统会自动释放。
例程:
mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include 
#include 

class myButton : public QPushButton
{
    Q_OBJECT
public:
    explicit myButton(QWidget *parent = nullptr);
    ~myButton();
signals:

public slots:
};

#endif // MYBUTTON_H

mybutton.cpp

#include "mybutton.h"
#include 

myButton::myButton(QWidget *parent) : QPushButton(parent)
{

}

myButton::~myButton()
{
    qDebug() << "按钮被析构";
}

mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include 

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();
};

#endif // MYWIDGET_H

mywidget.cpp

#include "mywidget.h"
#include 
#include "mybutton.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    /* 对于父窗口,坐标系相对于屏幕
     * 原点:相对于屏幕左上角
     * x:往右递增
     * y:往下递增
     */
    move(750,300);

    QPushButton *b1 = new QPushButton(this);
    b1->setText("^_^");

    /* 对于子窗口,坐标系相对于父窗口
     * 原点:相对于父窗口左上角
     * x:往右递增
     * y:往下递增
     */
    b1->move(0,0);
    b1->resize(200,200);//设置按钮大小

    QPushButton *b2 = new QPushButton(b1);
    /* 对于子控件,坐标系相对于父控件
     * 原点:相对于父控件左上角
     * x:往右递增
     * y:往下递增
     */
    b2->move(50,50);
    b2->setText("@_@");

    myButton *b3 = new myButton(this);
    b3->setText("析构测试按钮");


}

MyWidget::~MyWidget()
{

}

当主窗口关闭,myButton的析构函数将被调用。在这里插入图片描述

7. 创建一个MainWindow

菜单栏-工具栏

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第16张图片
mainwindow.cpp

#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //菜单栏
    QMenuBar *mBar = menuBar();

    //添加菜单
    QMenu *pFile = mBar->addMenu("文件");

    //添加菜单项,添加动作
    QAction *pNew = pFile->addAction("新建");

    connect(pNew,&QAction::triggered,
            [=]()
    {
        qDebug()<<"新建按键被按下";
    }
    );

    pFile->addSeparator();//添加分割线
    QAction *pOpen = pFile->addAction("打开");


    //工具栏,菜单栏的快捷方式
    QToolBar *toolBar = addToolBar("toolBar");

    //工具栏添加快捷键
    toolBar->addAction(pNew);

    QPushButton *b = new QPushButton(this);
    b->setText("^_^");
    //添加小控件
    toolBar->addWidget(b);
    connect(b,&QPushButton::clicked,
            [=]()
            {
                b->setText("123");
            }
    );

    //状态栏
    //核心控件
    //浮动窗口
}

MainWindow::~MainWindow()
{

}

状态栏

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第17张图片
mainwindow.cpp

#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //菜单栏
    QMenuBar *mBar = menuBar();

    //添加菜单
    QMenu *pFile = mBar->addMenu("文件");

    //添加菜单项,添加动作
    QAction *pNew = pFile->addAction("新建");

    connect(pNew,&QAction::triggered,
            [=]()
    {
        qDebug()<<"新建按键被按下";
    }
    );

    pFile->addSeparator();//添加分割线
    QAction *pOpen = pFile->addAction("打开");


    //工具栏,菜单栏的快捷方式
    QToolBar *toolBar = addToolBar("toolBar");

    //工具栏添加快捷键
    toolBar->addAction(pNew);

    QPushButton *b = new QPushButton(this);
    b->setText("^_^");
    //添加小控件
    toolBar->addWidget(b);
    connect(b,&QPushButton::clicked,
            [=]()
            {
                b->setText("=_=");
            }
    );

    //状态栏
    QStatusBar *sBar = statusBar();
    QLabel *label = new QLabel(this);
    label->setText("Normal text file");
    sBar->addWidget(label);
    //addWidget 从左往右添加
    sBar->addWidget(new QLabel("2",this));

    //addPermanentWidget 从右往左添加
    sBar->addPermanentWidget(new QLabel("3",this));

    //核心控件

    //浮动窗口
}

MainWindow::~MainWindow()
{

}

核心控件和浮动窗口

  1. 核心控件
    Qt学习第1天:基本操作(信号与槽等) 【笔记】_第18张图片
#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //菜单栏
    QMenuBar *mBar = menuBar();

    //添加菜单
    QMenu *pFile = mBar->addMenu("文件");

    //添加菜单项,添加动作
    QAction *pNew = pFile->addAction("新建");

    connect(pNew,&QAction::triggered,
            [=]()
    {
        qDebug()<<"新建按键被按下";
    }
    );

    pFile->addSeparator();//添加分割线
    QAction *pOpen = pFile->addAction("打开");


    //工具栏,菜单栏的快捷方式
    QToolBar *toolBar = addToolBar("toolBar");

    //工具栏添加快捷键
    toolBar->addAction(pNew);

    QPushButton *b = new QPushButton(this);
    b->setText("^_^");
    //添加小控件
    toolBar->addWidget(b);
    connect(b,&QPushButton::clicked,
            [=]()
            {
                b->setText("=_=");
            }
    );

    //状态栏
    QStatusBar *sBar = statusBar();
    QLabel *label = new QLabel(this);
    label->setText("Normal text file");
    sBar->addWidget(label);
    //addWidget 从左往右添加
    sBar->addWidget(new QLabel("2",this));

    //addPermanentWidget 从右往左添加
    sBar->addPermanentWidget(new QLabel("3",this));

    //核心控件
    QTextEdit *textEdit = new QTextEdit(this);
    setCentralWidget(textEdit);

    //浮动窗口
}

MainWindow::~MainWindow()
{

}

  1. 浮动窗口

Qt学习第1天:基本操作(信号与槽等) 【笔记】_第19张图片
mainwindow.cpp

#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //菜单栏
    QMenuBar *mBar = menuBar();

    //添加菜单
    QMenu *pFile = mBar->addMenu("文件");

    //添加菜单项,添加动作
    QAction *pNew = pFile->addAction("新建");

    connect(pNew,&QAction::triggered,
            [=]()
    {
        qDebug()<<"新建按键被按下";
    }
    );

    pFile->addSeparator();//添加分割线
    QAction *pOpen = pFile->addAction("打开");


    //工具栏,菜单栏的快捷方式
    QToolBar *toolBar = addToolBar("toolBar");

    //工具栏添加快捷键
    toolBar->addAction(pNew);

    QPushButton *b = new QPushButton(this);
    b->setText("^_^");
    //添加小控件
    toolBar->addWidget(b);
    connect(b,&QPushButton::clicked,
            [=]()
            {
                b->setText("=_=");
            }
    );

    //状态栏
    QStatusBar *sBar = statusBar();
    QLabel *label = new QLabel(this);
    label->setText("Normal text file");
    sBar->addWidget(label);
    //addWidget 从左往右添加
    sBar->addWidget(new QLabel("2",this));

    //addPermanentWidget 从右往左添加
    sBar->addPermanentWidget(new QLabel("3",this));

    //核心控件
    QTextEdit *textEdit = new QTextEdit(this);
    setCentralWidget(textEdit);

    //浮动窗口
    QDockWidget *dock = new QDockWidget(this);
    addDockWidget(Qt::RightDockWidgetArea,dock);
    //给浮动窗口添加一个文本框
    QTextEdit *textEdit1 = new QTextEdit(this);
    dock->setWidget(textEdit1);
}

MainWindow::~MainWindow()
{

}

小技巧:接口开头不是add就是set

对话框

模态和非模态对话框
  • 模态对话框:操作时只能操作当前对话框
  • 非模态对话框:操作当前对话框时,可同时操作其他对话框
    新建项目01day_06_Dialog,先以QMaiinWindow为基类:
    mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QDialog dlg;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QMenuBar *mBar = menuBar();
    setMenuBar(mBar);
    QMenu *menu = mBar->addMenu("对话框");

    QAction *p1 = menu->addAction("模态对话框");
    connect(p1,&QAction::triggered,
            [=]()
    {
        QDialog dlg;
        dlg.exec();//等待用户操作
        qDebug()<<"111111111111";//操作完会打印这句话
    });

    QAction *p2 = menu->addAction("非模态对话框");
    connect(p2,&QAction::triggered,
            [=]()
    {
       //QDialog dlg;//此种情况,运行后对话框由于没有等待用户操作,将会直接闪退,此时可将其当做类成员
       // 实现方式1:最简单
//       dlg.show();
//       qDebug()<<"22222222";
       //实现方式2:
//        QDialog *p = new QDialog(this);
//        p->show();//这种方式只有在关闭时才会释放,这就导致内部越用越少
        //实现方式3:
        QDialog *p = new QDialog;
        p->setAttribute(Qt::WA_DeleteOnClose);//关闭即释放
        p->show();
    });
}

MainWindow::~MainWindow()
{

}

对于非模态对话框,有三种实现方式:

  • 方式1:最简单

    //QDialog dlg;作为类成员
    dlg.show();
    
  • 方式2:可能会导致内存泄露

    QDialog *p = new QDialog(this);
    p->show();//这种方式只有在关闭时才会释放,这就导致内部越用越少
    
  • 方式3

    QDialog *p = new QDialog;
    p->setAttribute(Qt::WA_DeleteOnClose);//关闭即释放
    p->show();
    
标准对话框和文件对话框
  1. 标准对话框
    QAction *p3 = menu->addAction("关于对话框");
    connect(p3,&QAction::triggered,
            [=]()
    {
        QMessageBox::about(this,"about","关于qt");
    }
    );

    QAction *p4 = menu->addAction("问题对话框");
    connect(p4,&QAction::triggered,
            [=]()
    {
       int ret = QMessageBox::question(this,"question","are you ok?",
                                       QMessageBox::Ok,QMessageBox::Cancel);
       switch (ret) {
       case QMessageBox::Ok:
           qDebug()<<"I am ok";
           break;
       case QMessageBox::Cancel:
           qDebug()<<"I am bad";
           break;
       default:
           break;
       }
    }
    );

  1. 文件对话框
    QAction *p5 = menu->addAction("文件对话框");
    connect(p5,&QAction::triggered,
            [=]()
    {
        QString path = QFileDialog::getOpenFileName(
                    this,
                    "open",
                    "../",//路径设置
                    "souce(*.cpp *.h);;Text(*.txt);;all(*.*)");//过滤器,可自动换行
        qDebug() <<path;
    }
    );

你可能感兴趣的:(#,▶,Qt,▼,程序人生,QT,信号,槽,坐标系统)