QT入门(一)Qt工程简介、信号与槽初步练习

QT程序结构

程序特点

  • 跟普通程序一样,头文件,源文件,工程文件.pro
  • 头文件特点

    • QT系统头文件没有.h
    • 头文件和类名一样
    • 命名Q开头,前两个字母大写
  • 工程文件.Pro的相关介绍

# 模块
QT  += core gui
# 高于4版本添加本句内容,增加兼容
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# 生成程序的名称
TARGET = my_first

# 指定Makefile生成的类型 app lib···
TEMPLATE = app

#警告信息
DEFINES += QT_DEPRECATED_WARNINGS

# 源文件
SOURCES += \
        main.cpp \
        mywidget.cpp
# 头文件
HEADERS += \
        mywidget.h

# 增加对C++11的支持
CONFIG += C++11
  • 特点
    一个程序有多个对象时,默认情况下各个对象(窗口)是相互独立的,只有指定父类情况下,对象间才产生依赖关系,例如想在窗口对象上,建立一个按钮对象,那么按钮对象的父对象应该被设置为窗口对象。依赖关系确定只要父对象显示,那么子对象就会显示出来,子对象可以不必调用自身显示函数。
#include<QPushbutton>
int main(int argc,char **argv)
{
    QApplication a(argc,argv);
    QWidget w;
    w.setWindowTitle("李京京");

    QPushButton b;
    b.setParent(&w);
    b.setText("张超");
    b.move(100,100);

    QPushButton b1(&w);
    b1.setText("李京京");
    b1.move(200,100);
/*
 *如果不指定父对象,对象和对象(窗口和窗口没有关系),独立
 *a指定b为他的对象,a放在b的上面
 *指定父对象有两种方式:
 *       1)setParent
 *       2)通过构造函数传参
 *指定父对象,只要父对象显示,上面的子对象自动显示(不必在调用子对象显示函数)
*/
    w.show();
    return a.exec();
}
  • 窗口对象
    窗口或者其它可视对象创建以后,默认是隐藏的,只有调用显示函数时才会显示,编译运行程序时,如果没有调用显示函数,虽然没有看到任何东西,但程序已经在运行了,默认等不到用户处理它就会一直运行,我们可以通过任务管理器将它杀掉,或者通过IDE停止按钮将程序结束运行。

信号与槽

信号连接函数
connect(发出信号的对象地址,信号及所在类的地址,接收信号对象的地址,接受者的处理函数(槽函数)地址)
自定义信号
需要signals:关键字修饰,信号形式类似函数声明,只声明不填充信号发射用emit关键字修饰,槽函数与信号类型需要一致,无返回值,有无参数需要与信号形式保持一致。
信号重载
信号同名,不同参数时产生信号重载,connect函数不能区分信号类型而产生错误,需要用函数指针来进行区分,最好不要用QT4方式。QT4方式虽然简单编译阶段不能检测信号是否正确,只有在运行时才能检测到错误与否,对于大型软件项目,此类方法并不好

//定义两个重载信号
signals:
    void mysignal();
    void mysignal(int,QString);

//定义信号发射    
void SubWidget::myslot2()
{
    emit mysignal();
    emit mysignal(100,"1234");
}

//利用函数指针区分重载信号,避免二义性的产生
//函数指针需要添加定义域
//调用函数指针时直接调用即可
void (SubWidget::*funcSignal1)()=&SubWidget::mysignal;
void (SubWidget::*funcSignal2)(int,QString)=&SubWidget::mysignal;
connect(&w2,funcSignal1,this,&MainWidget::myslot3);
connect(&w2,funcSignal2,this,&MainWidget::myslot4);

Lambda函数
自定义槽函数需要声明、填充很麻烦,可以采用lambda函数,直接将槽函数函数体写在信号与槽的函数内部Lambda函数(匿名函数)是C++11以后添加的新特性,我们可以利用Lambda函数,代替槽函数,避免了槽函数声明构造等,增加代码效率,直接将槽函数写在函数体内部,使用时需要在工程文件里面添加CONFIG += C++11

 connect(&w2,&SubWidget::mysignal,this,&MainWidget::myslot3);
 void MainWidget::myslot3()
{
    this->show();
    w2.hide();
}

//利用匿名函数,直接将函数体写在连接函数内部比上面的写法要简洁
//【】中=代表将局部变量或者类中成员对象以值的方式传入函数体
//默认传入参数属性是只读属性,若想改变参数的值需要加mutable关键字[=]()mutable
connect(&w2,&SubWidget::mysignal,[=]()
{
    this->show();
    w2.hide();
}
);

实现主副窗口切换的QT程序(入门程序)

文件main.cpp mainwidget.cpp subwidget.h mainwidget.h subwidget.h Signal.pro

//main.cpp
#include "mainwidget.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //定义主窗口对象
    MainWidget w;

    //窗口标题
    w.setWindowTitle("这是主窗口");

    //窗口显示
    w.show();
    return a.exec();
}
//mainwidget.c
#include "mainwidget.h"
#include <QDebug>
//主窗口构造函数
MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    //b1按钮设置
    b1.setParent(this);
    b1.setText("切换副窗口");
    b1.move(100,100);

    //b1信号处理
    connect(&b1,&QPushButton::pressed,this,&MainWidget::myslot1);

    //副窗口标题设置
    w2.setWindowTitle("这是副窗口");

    //副窗口信号处理
    connect(&w2,&SubWidget::mysignal,this,&MainWidget::myslot3);
    //调整窗口分辨率
    resize(400,300);
}
MainWidget::~MainWidget()
{

}
//自定义槽函数1
void MainWidget::myslot1()
{
    this->hide();
    w2.show();
}
//自定义槽函数3
void MainWidget::myslot3()
{
    this->show();
    w2.hide();
}
//subwidget.cpp
#include "subwidget.h"
//副窗口构造函数
SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
    //b2按钮设置
    b2.setParent(this);
    b2.setText("切换到主窗口");
    b2.move(100,100);

    //修改分辨率
    resize(400,300);

    //b2按钮信号处理
    connect(&b2,&QPushButton::pressed,this,&SubWidget::myslot2);
}
//槽函数2
void SubWidget::myslot2()
{
    //发射信号  用emit修饰
    emit mysignal();
}
//mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QPushButton>
#include "subwidget.h"
class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();
    //声明槽函数
    void myslot1();
    void myslot3();
private:
QPushButton b1;
SubWidget w2;
};

#endif // MAINWIDGET_H
//subwidget.h
#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include <QPushButton>
class SubWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SubWidget(QWidget *parent = nullptr);
    //声明槽函数
    void myslot2();
signals:
    //定义自定义信号 只声明不定义  需要signals关键字修饰 
    void mysignal();
public slots:
private:
    QPushButton b2;
};

#endif // SUBWIDGET_H
//Signal.pro
//添加模块
QT       += core gui

//添加对QT4以上版本的支持  增加兼容性
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

//目标程序名字
TARGET = Signal
TEMPLATE = app

//编译警告输出
DEFINES += QT_DEPRECATED_WARNINGS

//源文件
SOURCES += \
        main.cpp \
        mainwidget.cpp \
    subwidget.cpp

//头文件
HEADERS += \
        mainwidget.h \
    subwidget.h

内存释放

QT中从 Q_OBJECT开始,会为每个对象建立内存依赖树,当对象使用完毕不用,手动释放内存,内存会被自动释放掉

//申请内存空间定义一个按钮
b3 =new QPushButton(this);
b3->setText("小按钮");
b3->move(50,50);

//不定义delete手动释放内存,直接关闭窗口
MainWidget::~MainWidget()
{
    qDebug()<<"对象被析构";
}

//能够看到仍然能够进入析构函数

坐标系统

每个对象都会以父对象的左上角为(0,0)坐标原点

猜你喜欢

转载自blog.csdn.net/z961968549/article/details/80853793
今日推荐