QT设计师
assistant 帮助手册
qmake -v 查看Qt版本
qmake -project 把项目源文件组织成项目描述文件 .pro
qmake 根据.pro 文件生成Makefile(文件和文件的依赖关系)
make 根据Makefile 得到目标
designer 设计器
所见即所的可视化界面设计得到的文件是.ui
uic(UI转换器) 把.ui文件 变成.h文件
===================================
qtcreator 集成开发工具(ICE)
qt头文件位置
/usr/include/qt4/
qt头文件 按照功能划分模块
主要文件 QtGui QtCore
了解文件 Qtsql QtXml QtNetWork QtOpenGL
Qt文件中.h和没有.h 没有.h是为了支持C++
这两个文件都是一样的
Qt库文件(就是头文件的实现文件)
/usr/bin/i386-linux-gnu
qt的库文件就是对头文件的分模块实现
============================================
重点:(一个程序一个文件)
第一个Qt程序
1.建立单独文件夹 写cpp程序
头文件#include <QApplication> qt应用程序
2.qmake -project 编译文件(使用g++ 非常麻烦,需要找到头文件和实现文件) 得到.pro
--------------------
在.pro 中添加
QT += widgets //表示需要加载和widget相关的库文件和头文件
TEMPLATE = app //将来该工程要被编译成应用程序
TARGET = Hello //可执行文件名字(a.out)
INCLUDEPATH += . //头文件路径
# Input
SOURCES += Hello.cpp //源文件
解决没有<QApplication>头文件的原因
-------------------------------
3.qmake 根据.pro 得到Makefile
4.make 得到执行文件
Qt中帮助文档 可以提供的内容
头文件 的模块
一个类的继承关系 继承自谁
被谁(QObject)
类的属性 和 继承关系
重点:公开的函数
构造函数
成员函数
public Slots(公有的槽)
信号函数 和 槽函数
signal slots
class A{
Q_OBJECT //这是一个宏
public slots:
void slot_func(){}//槽函数
};
Signals(信号函数)
class A{
Q_OBJECT
public:signals:
//或者 signals:
void signal_func();//信号函数
}
信号函数和槽函数和QT编程的核心
Qt4下 信号函数 只需要声明,不需要实现
5.6 保护函数
一般是事件处理函数
5.7 静态函数
不使用对象就可以直接调用的函数
5.8 类的详细说明
connect(&bu,&QPushButton::pressed,this,&MainWidget::close);
//标准槽函数
/*
* &bu:信号发出者
*&QPushButton::pressed 处理的信号 &发送者的类名::信号名称
* this:接受者
* &MainWidget::close 槽函数 信号处理函数 &接受的类名::槽函数名称
*/
信号必须有signals关键字声明
信号没有返回值,但是可以有参数
信号就是函数声明,只需声明,无需实现
使用:emit mySignal(); //发射信号
信号可以重载
在函数前面加 emit 关键字使用就可以了
x.setParent(this);
x = new QPushBtton(this);
这个是两种指定父对象的方法
就是谁在谁上面
指定父对象的好处:
不需要手动显示,父结束,子结束
QT中的字符串 QString C++字符串是string
QT4 connect(&w,SIGNAL(mySignal()),this,SLOT(deleteLater()));
QT5 connec(&w.&SubWidget::mySignal,this,&MainWidget::dealSub);
这两句话效果一样,第一种跟简洁
使用第一种方法:
第二个参数必须是"信号函数", 第四个参数必须是"槽函数"
优点:简单方便
缺点:会将函数名转换成字符串,不进行语法检查
使用第二种方法:
第二个参数必须是"信号函数", 第四个参数可以是
任意成员函数 普通全局变量 静态函数
优点:回进行语法检查
缺点:写起来麻烦
//Lambda表达式 匿名函数对象//C++11增加的新特性,项目文件: CONFIG +=C++11
//QT配合信号一起使用,非常方便
使用:
connect(p4,&QPushButton::clicked,
//方括号的使用方法:
// 可以传多个参数eg: [a,b,c]
// = 表示把所有局部变量、类中所有成员以值传递方式
// this 类中所有成员以值传递方式
// & 把外部所有局部变量、引用符号
[=](/*这里面可以传递参数*/) [mutable]
{
qDebug() << iscli;
}
);
----
坐标
没什么要说的
就是谁相对于谁来说,在哪里
move() 设置坐标
resize() 设置大小
QT内存释放机制(前提是有指针才使用这个)
//1)指定父对象后 2)直接或间接继承与QOject
//子对象如果是动态分配的new, 不需要手动delete
//系统会自动释放
------------------------
关于菜单
QMenuBar *mb=menuBar();
setMenuBar(mebar); //设定菜单栏
第一步:先添加“菜单栏” <QMenuBar>
第二步:在添加“菜单” <QMenu>
第三步:最后添加“菜单项(动作)”<QAction>
再最后各种信号处理
addMenu() //添加菜单
addAction() //添加菜单项
addSeparator() //添加分割线
关于工具
QToolBar *tool=addToolBar("toolBar");
工具栏就是菜单项的快捷方式 <QToolBar>
关于状态栏
QStatusBar *stat=statusBar();
标签可以添加在状态栏上
关于核心控件(就是文本中间那块打字的地方)
QTextEdit *texted=new QTextEdit(this); //创建文本编辑对象
setCentralWidget(texted); //设置中心小窗口
关于浮动窗口
QDockWidget *dock=new QDockWidget(this);
//设置浮动窗口在那一侧
addDockWidget(Qt::RightDockWidgetArea,dock);
可以添加其他控件
--------------------------------------
==============
模态对话框和非模态对话框(用的较少)
<QDialog> //对话框 主要用于模态和非模态
-----------------
标准对话框(常用)
<QMessageBox> //对话框 主要用于系统的
问题对话框about
文件对话框(常用)
<QFileDialog> //文件对话框
getOpenFileName(指定父对象,框名称,文件的绝对路径,过滤文件格式);
eg: QString s=QFileDialog::getOpenFileName(this,"open",
"/home/tarena/QT学习", //这里写绝对路径
"souce(*.cpp *.h *.pro);;Text(*txt);;all(*.*)" //过滤文件格式
);
问题对话框和文件对话框 基本上都是调用的静态函数
==========================
设计器内容
关于文本编辑
text() 返回文本编辑的内容
setText() 设置文本内容
setEchoMode() 设置显示方式
QLineEdit::Normal 显示内容
QLineEdit::NoEcho 不显示内容
QLineEdit::Password 密本显示
QLineEdit::PasswordEchoOnEdit
setTextMargins() 设置内容显示间隙(用的不多)
设置文本自动补全的例子:
QLineEdit *lineEdit = new QLineEdit(this);
QStringList wordList;
wordList << "alpha" << "omega" << "omicron" << "zeta";
QCompleter *completer = new QCompleter(wordList, this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
lineEdit->setCompleter(completer);
======
Label 标签
可以写文本
//下面两个都需要先添加资源文件
可以添加图片
setPixmap(Pixmap(路径));
可以添加Gif
QMovie *mymovie=new QMovie(路径);
ui->labelGif->setMovie(mymovie); //设置动画
mymovie->start(); //启动动画
ui->labelGif->setScaledContents(true); //自动适应大小
可以添加网址
setText("<h1><a href=\"https://www.baidu.com\">百度一下</a></h1>");
setOpenExternalLinks(true); //让外部链接生效
===========
show()与exe()
相同点:都是显示窗口
不同点:show()如果当前函数结束,则窗口消失,且无返回值
exe()显示窗口并阻塞,且有返回值
==============
QT样式表
调用函数:
QWidget::setStyleSeet()或者QAppliction::setStyleSheet()
color:设置前景色
background-color:设置背景颜色
border-image:url(图片路径) :设置背景图片
注:如果背景有图片,背景颜色就不起作用了
关于背景图片例子:
QPushButton{
border-width:4px;
border-image:url(路径) 4 4 4 4 stretch stretch;
//border让图片自动适应大小 这4个数字,表示从图片四周向内裁剪(和截图差不多)
}
伪装态
QPushBtton{
border:2px outest green
background:gray
}
伪状态列表
:checked button部件被选中
:disabled 部件被禁用
:enabled 部件被启用
:focus 部件获得焦点
:hover 鼠标位于部件上
:indeterminate checkbox或rediobutton被部分选择
:off 部件可以切换,且处于off状态
:on 部件可以切换,且处于on状态
:pressed 部件被鼠标按下
:unchecked button部件未被选中
代码参考:styleSheet文件
=====================
事件(模拟中断)
QT中所有的事件都继承与QEvent
QT将事件对象传给QObject的event()函数,这个函数不直接处理
而将事件对象的类型分派给特定的事件处理函数(eventhandler)
QWidget中的常用事件函数
keyPressEvent() //键按下
keyReleaseEvent() //键弹起
mouseDoubleClickEvent() //双击鼠标
mouseMoveEvent() //移动鼠标
mousePressEvent() //鼠标按下(可以自己判断Lift,Mid,Right)
mouseReleaseEvent() //鼠标弹起
注:在写事件的时候需要进行控件提升(除了主窗口)
格式化输出
QString str = QString("%1,%1").arg().arg();
信号的处理和忽略
接受信号(信号一旦被接受就不会在往下传递)
这时候需要调用原来的事件处理函数(再次发送信号)
控件名称::事件处理函数
TimerEevent() //定时器事件,这是系统内部调用
statTimer() //启动定时器,返回值是int
KillTimer(int id) //关闭定时器
注:可以同时启动多个定时器,根据ID来判断关闭那个定时器
帮助手册 看保护类型和 Event()
事件的接受和忽略
accpet() //接受事件
ignore() //忽略事件
(这两个一般用于关闭窗口)
事件过滤器
event() //就是事件分发给每个处理函数
也可以直接在Event中做处理,但需要强制转换类型
eventFilter() //就是对控件对象直接处理
返回值都是bool
注:事件过滤器和安装过滤器必须在同一线程才有效,
或者最后回到同一线程才有效
=======
复习篇
1)常用控件
Qt ui
ui->
ui_xxx.h 这个文件可以看到一些函数的实现
--1)按钮类
QPushButton
QToolButton
QRadioButton
--2)item
QListWidget
--3)容器类
QStackWidget
QWidget
QFrame
--4)编辑类
QComboBox
QLineEdit
QTextEdit
--5)显示类
QLabel
QLcdNumber
QProgressBar
--6)布局
水平
垂直
网格
布局属性
大小策略
最小大小
最大大小
容器(分类)
弹簧
--7)自定义控件(提升)
7.1)ui的控件和自定义的父类要一样
7.2)选中ui控件->提升
====================
绘图
//打开文件目录
QString path=QFileDialog::getOpenFileName(this,"Open","../","TXT(*.txt)");
QPainter 画家
QPaintDevice 绘图设备
画图需要重写绘图事件paintEvent(QPaintEvent *);
(如果在窗口绘图,必须在绘图事件里实现)
(Qt中如果形参不用,可以不写,C/C++不行)
--
创建画家对象
指定绘图设备
绘图操作x.drawxxx() //都是这一类的函数
定义画笔
将画笔交给画家
开始画图
setColor(Qt::red/*QColor(0,0,0)*/);设置颜色
setStyle() //设置风格
定义画刷
将画刷交给画家
setColor()
setStyle()
-这两个函数最好一起使用,不然效果不明显
。。。。
rect();
[结束]
//刷新窗口,让窗口重绘,让整个窗口重绘,也可以只重绘局部
update(); // 间接调用paintEvent()
--
QBitmap->(继承于)QPixmap
QPixmap:主要画彩色
load() 加载图片
QBitmap:只有黑白两色
绘图设备
-QPixmap:针对屏幕进行优化,和平台(显卡)相关,不能对图片修改
-QImage:于平台无关,可以对图片修改(像素点修改),在线程中绘图
-QPicture: 保存绘图的状态(二进制文件)
代码参考QBitmap QPixmap QPImage
==================
不规则窗口的创建(这个学的不好)
代码参考:No_Rule_Widget
========================
QT文件读写
-基类(QIODevice)
//打开文件目录
QString path=QFileDialog::getOpenFileName(this,"Open","../","TXT(*.txt)");
----
文件的通用操作
打开文件
关联路径
关闭文件
----
isEmpty() //判断文件是否为空
open() //打开文件
readAll() //读取全部文件
reafLine() //读取一条数据
atEnd() //判断是否读到文件结尾
close() //关闭文件
(这里包含一些编码的转换)
获取文件信息
#include <QFileInfo>
toUtf8() //将当前编码转换成UTF8支持中文
data() //转换成char*
代码参考:QFile
数据流的使用(二进制)
和C++中的文件流差不多
__FILE__ 文件的所在位置
__LINE__ 第几行代码
这个两个宏是C语言的全局宏
代码参考QDataStream
=========
使用QFile 是往本地文件中写数据,可见的,程序结束保留
使用QBuffer 是往内存文件(虚拟的)中写数据,不可见,程序结束不保留
(QBuffer在close后才算读写完成)
=========
QDir
exists() //判断目录是否存在
entryList() //访问目录
->QDir::Dirs //目录
->QDir::Files //普通文件
返回QStringList容器对象,保存所有的文件名
eg:
foreach(QString file,dir.entryList(QDir::Files))
qDebug() << file;
QStringList strl(d.entryList(QDir::Files)); //调用拷贝构造
for(int i=0;i<strl.size();i++)
qDebug() << strl[i];
//这个两个例子功能一样
=========
Qt中字符串于数字的转换
//QString -> 数字
str.toDouble();
..
//数字 -> QString
QString::number();
setNum();
==========
图片的镜像操作
QImage image(tempPath);
QImage mirr=image.mirrored(true,false);
QPixmap pix=QPixmap::fromImage(mirr);
==========
==================================
Qt下网络通信
TCP(类似于生活中的打电话)
回顾liunx:
客户端 服务器
sokcet 通信套接字 sokcet 监听套接字
connect bind
listen
accept 通信套接字
read/write read/write
close close
-----------------------------------------
Qt: QTcpSocket QTcpSever 监听套接字
connectToHost listen (将linux下bind和listen和在一起)
//如果连接成功,服务器会触发newConnection信号
//->槽函数->取出建立连接好的套接字QTcpSocket
发送数据write
//->如果数据传送成功,对方的通信套接字触发readyRead信号,需要在
//对应的槽函数做接受处理
如果成功和对方建立连接,通信套接字
就会自动触发connected信号(一般用在客户端)
如果对方主动断开连接,通信套接字
就会自动触发disconnected信号
常用函数
nextPendingConnection() //取出未决队列中来进行连接
pauseAccepting() //暂停接受新连接
peerAddress() //IP地址
peerPort() //端口号
write()
readAll()
注:只要发送信息就会触发信号
注:网络编程项目文件(.pro)加 QT+=network
========================================
UDP(类似于生活中的写信)
UDP(不分服务器和客户端)
liunx下
客户端 服务器
socket socket
bind
recvfrom/sendto recvfrom/sendto
close close
-------------------------------------
Qt: QUdpSocket QUdpSocket
bind bind
readDatagram/ readDatagram/
//->如果数据传送成功,对方的通信套接字触发readyRead信号,需要在
//对应的槽函数做接受处理
WriteDatagram WriteDatagram
close close
UDP多播组播(类似群聊)
地址分为ABCD四类
组播是属于D类 244.0.0.0~244.0.0.255 还有其他的...
joinMulticastGroup() //加入
leaveMulticastGroup() //离开
注:bind要指定QHostAddress为AnyIPvp4
注:组播地址必须是D类地址
======================
定时器对象(QTimer)
timeout //定时器启动自动触发timeout信号
start() //启动
stop() //关闭
isActive() //当前状态
==================================
TCP发送文件的思想(前提是有服务器和客户端以连接)
需要使用QFile来进行文件读写,使用QTcpSocket来进行网络传输
客户端 服务器
接受数据(通过网络来传输) 首先要选择文件(QFileDialog)
拆包 获取文件信息(QFileInfo)(名称、大小...)
创建本地文件 对文件信息进行组包(格式化)
写入文件(发多少,写多少) 读文件
发送数据(通过网络来传输)
首先发送文件头部防止粘包(使用QTimer来延时) 注:TCP有粘包问题
==================================
Qt的线程
<线程主要用于将较为复杂的程序单独分离出来运行>
liunx下的线程
pthread_create(id,NULL,执行函数,NULL); //较为简单
Qt4.7下的线程(简单不灵活)
必须写一个类继承QThread类
然后类中有一个公用函数 void run();//线程执行函数,其它的都不算,只有这一个名称必须是run
启动子线程
不能直接调用run,只能使用start()间接调用(类似updata(重绘窗口))
启动子线程并调用线程处理函数
quit(); //处理完数据,结束线程
wait(); //阻塞等待线程结束
注:window下主窗口线程结束,子线程不会立马结束
---
Qt下线程的另一种写法(灵活不简单)
必须写一个类继承QObject类
然后类中有一个公用函数 void 名称(); //名称随意取
(1)创建线程不能指定父对象(自定义的),如果指定了父对象就无法加入到子线程了
(2)创建QThread对象(这个可以指定父对象)
(3)把自定义的线程类加入到子线程
自定义线程对象.moveToThread();
启动子线程
start(); //只是启动线程,但是不调用线程处理函数
[不能直接调用线程处理函数
直接调用,导致,线程处理函数和主线程在同一线程]
线程函数的启动必须通过 Signals-Slot的方式启动
//面试中
connect()第五个参数的作用,连接方式:默认、队列、直接
多线程才有意义
默认的时候
多线程默认使用:队列
单线程默认使用:直接
队列:槽函数所在的线程和接收者一样
直接:槽函数所在线程和发送者一样
注:Qt线程处理函数内部不允许操作图形界面,只做纯数据处理
quit(); //处理完数据,结束线程
wait(); //阻塞等待线程结束
注:window下主窗口线程结束,子线程不会立马结束
=======================================
线程绘图(QImage)
在子线程中做绘图操作
需要指定一个绘图设备
在将绘图设备以信号的方式发送给主线程
再通过绘图事件,画到主窗口上
=======================================
QT中的数据库
注:项目模块中需要加 QT+=sql
数据库头文件 #include <QSqlDatabase> //数据库
QSqlDatabase::drivers(); //打印QT支持的数据库驱动
QSQLITE:文件型数据库(.db) //本地数据库,不支持数据累加,可以是使用文本文件创建(可能出现转码问题)
//这种库和其他库的区别,不需要登陆,可以直接连接
QSQlMYSQL
添加数据库
//这个有返回值
返回值=QSqlDatabase::addDatabase("数据库驱动"); //第二参数的作用就是一个标示(一意义)
两种操作数据库的方式
(1)
#include <QSqlQuery> //QSqlQuery类提供了一种执行和操作SQL语句的方法
#include <QSqlQueryModel> //QSqlQueryModel类为SQL结果集提供只读数据模型
QSqlQuery::exec(字符串); //执行标准SQL语句
QSqlQuery::exec(); //判断上一句语句是否执行成功 true,否则false
QSqlQuery::prepare(); //为执行准备SQL查询
例子:
prepare("insert into lx values(:id,:name)");
QVariantList list; //变化链表
list << x << x << x;
QSqlQuery::execBatch(); //批量执行
QSqlQuery //提供SQL语句的执行方法
QSqlQuery query; //如果上面给了第二给参数,这里写成query(返回值)
query.exec("sql语句字符串");
可视化操作数据库
Qt下:模型视图
MFC下:文档视图
Qt不直接提供Oracle数据驱动,需要手动加入
#include <QNetworkAccessManager> //允许应用程序发送网络请求并接收回复
#include <QNetworkRequest> //保存一个用QNetworkAccessManager发送的请求
#include <QNetworkReply> //包含使用QNetworkAccessManager发送的请求的数据和标题
#include <QUrl> //为使用url提供了一个方便的接口
==================================
通用函数
size() //返回大小
setText(string); //设置文本
move(x,y) //设置位置
setWindowTitle(string) //设置主窗口标题
resize(long,wide) //设置大小
width() 宽
toPlainText() //获取TextEdit编辑区的内容
append() //追加
height() 高
exe(); //返回标准按钮值 (QMessageBox::Yes)类似这就标准按钮值
===========================================================
===========================================================
===========================================================
Qt程序的打包方法(Win10)Qt4.5版本的
第一步:将你要打包的程序使用Relese运行一次
第二步:在项目文件夹下会生成一个关于Relese的文件夹,将其中的.exe文件拷贝出来
单独放在一个文件夹中
第三步:搜索Qt 5.5 for Desktop(类似终端的东西)打开
第四步:在这个终端上输入cd/d 路径(刚才的放.exe的文件夹),然后在输入
windeployqt 程序名 回车结束(这一步是将所需库全部考过来)
当前.exe已经可以运行(只能在文件夹中运行)
第五步:通过Enigma Virtual Box这个软件经行打包
在第一栏上添加程序路径(.exe的),第二栏不用管,然后
点击添加(Add),将这前单独文件中的所有文件全部托进入来,
在选择 文件选项(Files Options) 选择是否将文件解压,
最后打包(Process)
---
//第六步:最后去程序打包的路径找到已经打包好的.exe文件,结束