QT探索篇:1

新建一个QT文件之后它会自动先为你chuang'j 创建好三个文件,1个.h文件,1个main.cpp文件,1个filename.cpp文件,后面的mymainwindow文件是我最后创建的

首先对各个文件进行一下初步介绍:

//main.cpp文件

#include "mywindow.h"
#include <QApplication>    //包含头文件 应用程序

//程序入口 argc命令行的变量数量,argv命令行的变量数组
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);      //应用程序对象a,QT中有且只有一个程序对象
    MyWindow w;            //创建mywidget对象w  mywidget的基类是QWidget
    w.show();        //窗口默认是不会弹出来的,如果想弹出来就需要调用show方法

//a.exec()进入消息循环队列,防止窗口一闪而过
    return a.exec();
}

这个是系统自动为我们生成的类似于版本介绍文件 :(.pro文件)

QT       += core gui        //QT包含的模块:两个模块core   gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于4版本   包含widgets模块

TARGET = QT_2019_7_24_first_one_project     //目标,生成的可执行的.exe文件的可执行程序
TEMPLATE = app  //TEMPLATE模板   app应用程序


SOURCES += main.cpp\   //源文件包含很多.cpp文件
        mywindow.cpp

HEADERS  += mywindow.h   //头文件
//mymainwindow.h

#ifndef MYWINDOW_H    //防止重复编译 #pragma one
#define MYWINDOW_H

#include <QMainWindow> //头文件

class MyWindow : public QMainWindow //继承
{
    Q_OBJECT          // 写了这个宏就支持QT中的信号和槽机制

public:
    MyWindow(QWidget *parent = 0);    //构造函数
    ~MyWindow();          //析构
};

#endif // MYWINDOW_H

QT中命名规范以及快捷键:
1.类名首字母大写
2.单词与单词之间首字母大写
3.函数,变量,首字母小写  单词与单词之间 首字母大写
1.运行:ctrl+R
2.编译:ctrl+B
3.查找:ctrl +F
4.帮助文档F1
5.字体缩放:ctrl+滚轮
6.自动对齐ctrl+i
7.整行移动ctrl+shife+↑或者↓
8.同名之间的.h/.cpp切换

注销多行就是先选中,再按下ctrl + /

 

#include "mymainwindow.h"  
#include <QApplication>
#include<QPushButton>
#include"newbutton.h"
myMainWindow::myMainWindow(QWidget *parent)
    : QMainWindow(parent)    //初始化,在.h文件中如果继承了谁的类就要使用谁的类来初始化
{
       //btn->show();//show用的是顶层的方法弹出,如果想在mywidget窗口中弹出,就需要依赖         mywidget,这样直接弹出的话就是一个窗口,一个按钮,不存在依赖关系
    //第一种创建按钮的方法
    QPushButton * btn = new QPushButton;
    btn->setParent(this);//设置父亲
    btn->setText("德玛西亚");  //设置文字,将char*隐式类型转换成Qstring
    btn->resize(100,50);//调节按钮大小

    //创建按钮的第二种方法
    QPushButton * btn2 = new QPushButton("第二按钮",this);
    //重置窗口大小
    this->resize(600,400);     //前面的this可以省略,但是为了直观我们这里就加上
    //移动按钮
    btn2->move(500,0);
    btn2->resize(100,100);
    //重置窗口标题
    setWindowTitle("大吉大利,今晚吃鸡");
    setFixedSize(600,400);//设置固定窗口大小(锁死),不允许缩放,右下角再也没有放大放小的按钮

    //创建按钮的第三种办法就是使用自定义的类来创建,但是这个类必须继承于QPushButton
    NewButton * Newbtn = new NewButton;       //NweButton 就是我们自定义的类
    Newbtn->setText("关闭");
    Newbtn->setParent(this);
    Newbtn->resize(100,50);

    Newbtn->move(200,200);

    //最后这个是一个连接信号和槽的系统函数,我们给定的功能是:按下第三种创建的按钮,就关闭窗口
    connect(Newbtn,&NewButton::clicked,this,&NewButton::close);
    //this代表的就是当前所在的类

}

myMainWindow::~myMainWindow()
{

}

结果如下图:点击关闭按钮,就就可以关闭了 

newbutton.h和newbutton.cpp内部是这样的

#ifndef NEWBUTTON_H
#define NEWBUTTON_H

#include <QWidget>
#include<QPushButton>
class NewButton : public QPushButton
{
    Q_OBJECT
public:
    explicit NewButton(QWidget *parent = 0);

signals:

public slots:
};

#endif // NEWBUTTON_H
#include "newbutton.h"
#include <QPushButton>
NewButton::NewButton(QWidget *parent) : QPushButton(parent)
{

}

其实我们并没有做什么,代码都是系统生成的继承,以及构造,析构,我们需要做的是就是把继承改为继承QPushButton就可以了 ,然后在其它.cpp文件中想要使用这个类只需要包含它的.h文件就可以了。

QT中的信号和槽:(也就是上面的 最后一行代码,点击按钮就可以关闭窗口的函数的参数)
connet:(信号的发送者,发送的信号(信号的地址),信号的接收者,处理的函数(槽函数)的地址)
connect(myBtn,&MyButton::clicked,this,&QWidget::close);点击按钮关闭窗口 ,第一个参数是你的按钮
 

自定义的信号和槽函数:
信号和槽函数要进行连接就需要四个参数,第一个是发出信号的发送者,一个信号的接收者,一个是发送出去的信号,另一个是槽函数 这次我们又添加了两个.h文件用来创建两个类,一个作为发送者(teacher),一个作为接收者(student)

//student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots:
    //自定义槽函数的的地方
    //高版本可以写到public下或者全局函数
    //槽函数返回值void
    //槽函数既需要声明也需要实现
    //槽函数可以有参数也可以发生重载
    void treat();           //我们定义了两个槽,一个有参一个无参
    void treat(QString foodname);
};

#endif // STUDENT_H
//teacher.h
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = 0);

signals:
    //自定义的信号需要写到singnals下面
    //返回值类型必须是void
    //信号只需要声明不需要实现
    //信号可以有参数,可以发送重载
    void hungry();         //自定义两个信号函数有参和无参
    void hungry(QString foodname);  //有参

public slots:
};

#endif // TEACHER_
//widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include"teacher.h"
#include"student.h"
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
    Teacher *zt;            //我们在这里定义了两个类对象的指针
    Student *st;
    void classover();         //以及一个发送信号函数

};

#endif // WIDGET_H

main函数中跟之前一样。

//student.cpp
#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{

}
void Student::treat()    //实现两个函数
{
    qDebug()<<"请老师吃饭";

}

void Student::treat(QString foodname)
{
    //请老师吃饭 老师要吃 "豆角茄子"
    //qDebug()<<"请老师吃饭"<<"老师要吃"<<foodname;   //foodname是QString类型,而<"请老师吃饭"<<"老师要吃"是char*类型,下面来一个类型转换
    qDebug()<<"请老师吃饭"<<"老师要吃"<<foodname.toUtf8().data();//结果:请老师吃饭 老师要吃 豆角茄子

}
//上面几行讲了一个有关类型转换的函数,转换成char*类型
//teacher.cpp不做任何处理,因为只需要发出信号即可
#include "teacher.h"

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

}


 

//widget.cpp

#include "widget.h"
//需求,创建两个类,Teacher类 Student类
//下课后老师发送一个信号饿了,由学生响应信号,处理信号的槽函数 请客吃饭
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

    zt = new Teacher(this);  //指明父亲是谁,就是当前类,然后定义两个对象,因为传参的时候就是定义了两个teacher * zt所以这里直接new就可以了,zt本来就是teacher *  
    st = new Student(this);
    //连接老师和学生
    //connect(zt,&Teacher::hungry,st,&Student::treat);  //连接的是无参函数
    //调用下课函数,因为老师不能一直处于饥饿状态必须是下课之后老师才会发送饥饿的信号,在classover有发送信号的关键字
//下面两个是有参调用的函数指针
    void (Teacher::*ww)(QString) = &Teacher::hungry;   //首先定义两个函数指针来指向有参的函数,因为connect连接到的时候要发生重载 但是无法指定参数,所以我们在外面就先确定好函数地址
    void (Student::*ss)(QString) = &Student::treat;
    connect(zt,ww,st,ss);
    classover();
}
void Widget::classover()//必须下课了才可以老师发送饿了信号然后学生请老师吃饭,这个下课信号由classover函数发送
{
    //触发老师饿了的信号
    //老师饿了的信号属于自定义的信号,出发自定义信号的关键字emit
    //emit zt->hungry();//激发函数,//进行有参的时候就不能调用无参的函数了
    emit zt->hungry("豆角茄子");  //但是为啥传参是在这个时候

}

弹出窗口打印这个 

上面这这代码就是,只要运行起来老师就饥饿了,看着很不爽,我们创建一个按钮,然会按下按钮老师再饥饿,这个按钮就相当于是出发老师饥饿信号

#include "widget.h"
//需求,创建两个类,Teacher类 Student类
//下课后老师发送一个信号饿了,由学生响应信号,处理信号的槽函数 请客吃饭
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

   zt = new Teacher(this);
   st = new Student(this);
   //不能一运行就下课,设置一个按钮,按下按钮才下课
   QPushButton * btn = new QPushButton("下课",this);
   this->resize(600,400);
   //btn->resize(100,100);
   btn->move(500,0);
   void (Teacher::*ww)(void) = &Teacher::hungry;
   void (Student::*ss)(void) = &Student::treat;
   connect(btn,&QPushButton::clicked,zt,ww);     //信号连接信号,按钮连接老师的饥饿信号,
   connect(zt,ww,st,ss);//饥饿信号触发之后然后学生的槽函数就会给予响应
   //disconnect(zt,ww,st,ss);    //断开连接,断开信号和槽
}
//用到了两次连接,一次连接的是按钮和老师饿了这个信号,第二个连接函数连接的是,老师饿了以及执行的槽函数。

只要点击下课按钮,就会弹出请老师吃饭。

之后我又增加了一次改变。

#include "widget.h"
//需求,创建两个类,Teacher类 Student类
//下课后老师发送一个信号饿了,由学生响应信号,处理信号的槽函数 请客吃饭
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

    zt = new Teacher(this);
    st = new Student(this);
    QPushButton * btn = new QPushButton("下课",this);
    this->resize(600,400);
    //btn->resize(100,100);
    btn->move(500,0);
    void(Widget::*clas)(void) = &Widget::classover;
    void (Student::*sse)(QString) = &Student::treat;
    void (Teacher::*wwe)(QString) = &Teacher::hungry;
    connect(btn,&QPushButton::clicked,this,clas);
    connect(zt,wwe,st,sse);
}
void Widget::classover()
{
    //触发老师饿了的信号
    //老师饿了的信号属于自定义的信号,出发自定义信号的关键字emit
    //emit zt->hungry();//激发函数,//进行有参的时候就不能调用无参的函数了
    emit zt->hungry("豆角茄子");  //但是为啥传参是在这个时候

}
//关于上面这段函数我是这样想的,点击按钮之后并不是按钮直接把信号发送给饿了信号,而是发送给下课了函数,由下课了函数内部再把信号发送给饿了信号,然后学生类的槽函数进行处理,请老师吃饭,并且这次之前的代码调用的是无参的函数,这里我改用有参函数

只要点击按钮就弹出有参函数内部内容

void(Widget::*clas)(void) = &Widget::classover;
   void (Student::*sse)(QString) = &Student::treat;
   void (Teacher::*wwe)(QString) = &Teacher::hungry;
   connect(btn,&QPushButton::clicked,this,clas);
   connect(btn,&QPushButton::clicked,this,&Widget::close);//上面这段代码增加这一行可以实现一个信号控制多个槽,即打印内容又关闭窗口
   connect(zt,wwe,st,sse);

信号和槽的拓展:
1.信号可以连接信号
2.信号和槽可以断开dsiconnect
3.一个信号可以出发多个槽函数
4.多个信号可以连接一个槽函数
5.信号和槽的参数必须一一对应,参数个数必须一一对应吗?不一定

信号的参数个数可以多与槽函数的参数个数,反之不可以,但是类型必须一一对应,(意思就是可以少,但是其余的参数必须相等)
 //void (Student::*sse)(QString) = &Student::treat;
//void (Teacher::*wwe)(QString) = &Teacher::hungry;
QString就是参数,上面的是槽函数,下面的是信号函数(当时自己设置的)

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值