b站学习视频:https://www.bilibili.com/video/BV1XW411x7NU?p=8
p1——p12
学习点
首先新建一个空白的工程文件(开始写代码不要用Application模板)
一般命名变量都是AaaaBbbb命名,函数是aaaaBbbb命名
一般轻量级就使用c++的QT内置的sqlite数据库,比较方便。大型服务器端才需要使用MYSQL
ctrl+l是运行快捷键

QApplication a(argc,argv)//有且只有一个应用程序类对象——a
int main//里面的参数无所谓
return a.exec();//也可以拆开写,让程序一直运行,等待用户操作
Mywidget继承于Qwidget
Q_OBJECT是指信号与槽
在添加头文件时,由于头文件被分为了不同的模块范围,加入头文件之后应该加入对应模块缩小搜索范围

在"应用程序输出"可以关闭程序
创建按钮等控件的时候默认不显示。
关于父、子对象
①如果不指定父对象,对象之间无关系。如a指定b为它的父对象,则a控件会放在b上面。
②指定了父对象,父对象显示,则子对象也会自动显示
③指定父对象的方式有两种:set parent 或者构造子对象的时候传入父对象参数
注意:子对象的实现(构造)可以另外设一个cpp文件在父对象构造函数里一起实现,从而精简主函数
但是千万不能在构造函数里才定义子对象,这样是局部对象,构造函数结束子对象就自动消失了。我们可以在最初定义父对象时,也定义子对象,而不是等到初始化才定义。
信号槽机制:如按下按钮,发出了信号,所有部件都可以接受到信号,但是只有提前设置好的,对它感兴趣的部件才会对此作出反应。
connect连接信号与槽
mySlot是自定义的函数,在下面进行具体函数编写。
按下,换一个按钮文本,同时隐藏另一个按钮
注意:子对象由于不能直接调用父窗口,运用信号槽机制,对父窗口发送信号,父窗口槽函数处理。
信号可以重载,改变信号函数的参数即可。
QDebug用法=cout
信号重载可能导致出现二义性,利用两个指针函数能够将重载函数与原函数进行区分(Qt5做法)
Qt4可以直接用含参数的重载函数,更加方便,但是可能出错。
QByteArray中toUtf8()能够转字符格式
Lambda表达式,匿名函数对象,配合信号槽使用
CONFIG+=C++11
函数无名字,在connect函数中间以 [] (形参){}代替
[] 将外部变量传进{}函数,[=]则以值传递方式(拷贝,安全),而加mutable参数值才能修改,不要用[&]
按钮如close是触发了一个回调函数(中断),而不是直接直接关闭窗口
!!如果代码有后缀为 .pro.user 的文件,需要把此文件删除,因为此文件保存之前项目编译环境信息
工程一
//01_QtTest.pro工程文件
#-------------------------------------------------
#
# Project created by QtCreator 2015-12-30T10:04:52
#
#-------------------------------------------------
#模块
QT += core gui
#高于4版本,添加 QT += widgets ,为了兼容Qt4
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#应用程序的名字
TARGET = mike
#指定makefile的类型, app
TEMPLATE = app
#源文件 .cpp文件
SOURCES += main.cpp\
mywidget.cpp
#头文件 .h文件
HEADERS += mywidget.h
//mywidget.h头文件
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class MyWidget : public QWidget
{
//Q_OBJECT //信号与槽的时候需要
public:
MyWidget(QWidget *parent = 0);
~MyWidget();
};
#endif // MYWIDGET_H
//mywidget.cpp文件
#include "mywidget.h"
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
}
MyWidget::~MyWidget()
{
}
//main.cpp文件
#include "mywidget.h"
//QApplication应用程序类
//Qt头文件没有.h
//头文件和类名一样
#include <QApplication>
int main(int argc, char *argv[])
{
//有且只有一个应用程序类的对象
QApplication a(argc, argv);
//MyWidget继承与QWidget, QWidget是一个窗口基类
//所以MyWidget也是窗口类
//w就是一个窗口
MyWidget w;
//窗口创建默认是隐藏,需要人为显示
w.show();
//让程序一直执行,等待用户操作
//等待事件的发生
a.exec();
return 0;
}
工程二
//02_HelloQt.pro文件配置
QT += widgets
SOURCES += \
main.cpp
//main.cpp文件
#include <QApplication>
#include <QWidget> //窗口控件基类
#include <QPushButton>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget w;
w.setWindowTitle(QString("主要看气质")); //设置标题
/*如果不指定父对象,对象和对象(窗口和窗口)没有关系,独立
* a指定b为它的父对象,a放在b的上面
* 指定父对象,有2种方式:
* 1)setParent
* 2)通过构造函数传参
* 指定父对象,只需要父对象显示,上面的子对象自动显示
*/
QPushButton b;
b.setText("^_^"); //给按钮设置内容
b.setParent(&w); //指定父对象
b.move(100, 100); //移动坐标
QPushButton b1(&w); //通过构造函数传参
b1.setText("abc");
w.show();
app.exec();
return 0;
}
工程三
#-------------------------------------------------
#
# Project created by QtCreator 2015-12-30T10:49:47
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = 03_SignalAndSlot
TEMPLATE = app
SOURCES += main.cpp\
mainwidget.cpp \
subwidget.cpp
HEADERS += mainwidget.h \
subwidget.h
CONFIG += C++11
//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();
public slots:
void mySlot();
void changeWin();
void dealSub();
void dealSlot(int, QString);
private:
QPushButton b1;
QPushButton *b2;
QPushButton b3;
SubWidget subWin;
};
#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 = 0);
void sendSlot();
signals:
/* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
void mySignal(int, QString);
public slots:
private:
QPushButton b;
};
#endif // SUBWIDGET_H
//mainwidget.cpp
#include "mainwidget.h"
#include <QPushButton>
#include <QDebug> //打印
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
//::是作用域符号,类似. 表示调用MainWidget对象的构造函数MainWidget
//而后面 QWidget(parent)则是指定调用QWidget 下构造函数,否则派生类会调用基类默认构造函数
//解释链接https://zhuanlan.zhihu.com/p/31310536
{
b1.setParent(this);
b1.setText("close");
b1.move(100, 100);
b2 = new QPushButton(this);
b2->setText("abc");
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);
/* 信号:短信
* 槽函数:接收短信的手机
*/
setWindowTitle("老大");
//this->setWindowTitle("老大");
b3.setParent(this);
b3.setText("切换到子窗口");
b3.move(50, 50);
//显示子窗口
//subWin.show();
connect(&b3, &QPushButton::released, this, &MainWidget::changeWin);
//处理子窗口的信号
// void (SubWidget::*funSignal)() = &SubWidget::mySignal;
// connect(&subWin, funSignal, this, &MainWidget::dealSub);
// void (SubWidget::*testSignal)(int, QString) = &SubWidget::mySignal;
// connect(&subWin, testSignal, this, &MainWidget::dealSlot);
//Qt4信号连接
//Qt4槽函数必须有slots关键字来修饰
connect(&subWin, SIGNAL(mySignal()), this, SLOT(dealSub()) );
connect(&subWin, SIGNAL(mySignal(int,QString)),
this, SLOT(dealSlot(int,QString)) );
// SIGNAL SLOT 将函数名字 -> 字符串 不进行错误检查
//Lambda表达式, 匿名函数对象
//C++11增加的新特性, 项目文件: CONFIG += C++11
//Qt配合信号一起使用,非常方便
QPushButton *b4 = new QPushButton(this);
b4->setText("Lambda表达式");
b4->move(150, 150);
int a = 10, b = 100;
connect(b4, &QPushButton::clicked,
// = :把外部所有局部变量、类中所有成员以值传递方式
// this: 类中所有成员以值传递方式
// & : 把外部所有局部变量, 引用符号
[=](bool isCheck)
{
qDebug() << isCheck;
}
);
resize(400, 300);
}
void MainWidget::dealSlot(int a, QString str)
{
// str.toUtf8() -> 字节数组QByteArray
// ……data() -> QByteArray -> char *
qDebug() << a << str.toUtf8().data();
}
void MainWidget::mySlot()
{
b2->setText("123");
}
void MainWidget::changeWin()
{
//子窗口显示
subWin.show();
//本窗口隐藏
this->hide();
}
void MainWidget::dealSub()
{
//子窗口隐藏
subWin.hide();
//本窗口显示
show();
}
MainWidget::~MainWidget()
{
}
//subwidget.cpp
#include "subwidget.h"
SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
this->setWindowTitle("小弟");
b.setParent(this);
b.setText("切换到主窗口");
connect(&b, &QPushButton::clicked, this, &SubWidget::sendSlot);
resize(400, 300);
}
void SubWidget::sendSlot()
{
emit mySignal();
emit mySignal(250, "我是子窗口");
}
//main.cpp
#include "mainwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget w;//执行MainWidget的构造函数
w.show();
return a.exec();
}