1 qt是什么?
跨平台的c++图形用户界面应用程序框架。
搭建环境
创建工程
基本功能介绍
编译运行
框架介绍
工程文件分析
2 第一个QT程序
Pro工程文件解析:
#模块
QT += core gui
#兼容QT4
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#程序名字
TARGET = day1_test
#指定makefile的类型
TEMPLATE = app
其他模块:webkit sql network muiltmedia 等等
3 指定父对象
添加按钮
#include
QPushButton b;
b.setText("设置按钮");
b.show();
如果不指定父对象直接show,会以两个窗口显示。
两种方式:setparent 构造函数指定
父对象自动管理子对象。
b.move(100,200);
SetGeometry(100,100,40,20);
通过move可以修改控件的坐标。
4 标准信号与槽
在mywidgrt里面定义两个按钮:
QPushButton b1;
QPushButton b2;
构造函数:
b1.setParent(this);
b1.setText("b1");
b1.show();
b2 = new QPushButton(this);
b2->setText("b2");
b2->move(0,100);
b2->show();
做以下功能:点击按钮 关闭窗口。
F1查看帮助文档。
分析。
connect(谁来发信号,信号,谁来接受,槽);
connect(&b1,&QPushButton::pressed,this,&MyWidget::close);
5 自定义槽函数
任意的成员函数,普通全局函数,静态函数
槽函数需要和信号一致,参数 返回值(没有返回值)
connect(b2,&QPushButton::released,this,&MyWidget::mySlot);
void MyWidget::mySlot()
{
b2->setText("myslot");
}
也可以由其他空间接受槽函数
connect(b2,&QPushButton::released,&b1,&QPushButton::hide);
可以任意指定,也可以一个信号,有多个槽函数。
6 课堂练习: 两个窗口之间切换
1 创建第二个视图
2 第一个视图持有第二个视图引用 通过hide第一个窗后,show第二个窗口 完成第一个到第二个视图切换
3 signals:/* 关键字申明 无返回值 可以有参数 只需申明 无需定义*/
void sendSignal();
第二个视图定义一个信号
点击按钮,发射信号emit sendSignal();
4 在第一个视图中接受第二个视图的信号
两个窗口大小不一样:resize(320,480);
5 拖动了一个窗口,会出现便宜,需要同步坐标 使用pos获取坐标
6 带参数的信号
第二个视图 添加一个信号
void sendSignal(int,QString);
第一个视图添加一个槽函数
void dealSlot(int,QString);
使用函数指针解决信号重载产生的歧义:
void (SecondView::*funSignal)() = &SecondView::sendSignal;
connect(&secView,funSignal,this,MyWidget::dealSecView);
void (SecondView::*funSignal2)(int,QString) = &SecondView::sendSignal;
connect(&secView,funSignal2,this,MyWidget::dealSlot);
或者Qt4
connect(&secView,SIGNAL(sendSignal()),this,SLOT(dealSecView());
缺点:不做类型检查 槽函数需要SLOT修饰 项目大了不易维护
中文如果不能识别 需要 toutf8().data()
7 lambda c++11新特性 配合信号使用很方便
需要在项目工程 CONFIG += C++11
QPushButton* b4 = new QPushButton(this);
b4->setText("lambda");
b4->move(150,150);
connect(b4,&QPushButton::pressed,[]()
{
qDebug()<<"1111";
});
【】捕获外部变量 可以直接写变量名
int a,b;
connect(b4,&QPushButton::pressed,[b4]()
{
b4->setText("pressed");
qDebug()<<"1111";
});
this 本类中的所有成员
= 把外部所有局部变量,类中所有成员以值传递 只读(即不可更改)
& 引用方式,传引用(尽量不用,因为局部变量会被释放,造成不可预知的后果)
int a = 5,b = 6;
connect(b4,&QPushButton::pressed,[a,b,b4]()
{
a = 10;
b4->setText("pressed");
qDebug()<<"1111"<<a<<b;
});
无法修改a 可以增加 mutable解决 【=】()mutable{}
This : 类中所有成员值传递
& 外部所有局部变量 引用传递 尽量不要使用
int a = 5,b = 6;
connect(b4,&QPushButton::pressed,[&]()
{
b4->setText("pressed");
qDebug()<<"1111"<<a<<b;
});
A b 已被释放
8 坐标系统
新建工程 move(0,0);
对于主窗口 坐标相对于屏幕左上角
QPushButton* b1 = new QPushButton(this);
b1->move(0,100);
b1->resize(50,50);
QPushButton* b2 = new QPushButton(b1);
b2->move(0,10);
b2->resize(20,20);
9 内存回收机制:自动回收
自定义控件
指定父对象 继承于QOBject
10 菜单栏 工具栏
新建继承于mainwindow的工程
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//菜单栏
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("Button");
toolBar->addWidget(b);
//状态栏
QStatusBar* sbar = statusBar();
QLabel* label = new QLabel(this);
label->setText("normal text ");
//从左->右
sbar->addWidget(label);
sbar->addWidget(new QLabel("utf8",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);
11 模态和非模态对话框
connect(p1,&QAction::triggered,
[=](){
QDialog dlg;
dlg.exec();
}
);
QAction* p2 = menu->addAction("非模态对话框");
connect(p2,&QAction::triggered,
[=](){
//成员 或者 new
//
QDialog dlg;
dlg.show();
QDialog* dia = new QDialog;
dia->setAttribute(Qt::WA_DeleteOnClose);
dia->show();
}
);
12 给对话框加按钮 标准对话框
QMessageBox::about(this,"关于","关于详细介绍");
int ret = QMessageBox::question(this,"infomaiton","sure close ?",
QMessageBox::Cancel | QMessageBox::Yes |QMessageBox::Open);
switch (ret) {
case QMessageBox::Yes:
qDebug()<<"click yes";
break;
}