一、Qt简介
- Qt历史
Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。
Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc)),以及一些宏,Qt很容易扩展,并且允许真正地组件(控件)编程。
Qt包括多达500个以上的C++类,还替供基于模板的collections,serialization,file,I/O device,directory management,date/time类。甚至还包括正则表达式的处理功能。
- QObject
QT项目中使用的类基本分为两种,一种为自定义的C++的类,另一种则为QObject类。QObject是所有Qt对象的基类。它的最主要特征是关于对象间无缝通信的机制:信号与槽。
QObject 以对象树的形式组织起来。当为一个对象创建子对象时,子对象会自动地添加到父对象的children()列表中。父对象拥有子对象的所有权,比如父对象可以在自己的析构函数中删除它的孩子对象。使用findChild()或findChildren()通过名字和类型查询孩子对象。
- QT项目目录介绍
- pro文件
pro文件是qmake的工程文件(project),通常我们也视他为qt项目的配置文档。
pro文档中的变量:
- QT变量:QT是声明组件模块的变量,默认包含core和gui模块,可用QT+=...来增加要用到的模块,或用QT-=...来去掉用不到的模块。
- TARGET变量:是目标文件名变量,默认为项目文件名。
- TEMPLATE变量:指定构建类型,常用的有:
- app: 构建应用;
- lib: 构建动态库或静态库;
- subdir:构建子目录项目。
- SOURCES变量:列出源文件
- HEADERS变量:指定头文件
- FORMS变量:指定项目中的UI文件
- CONFIG变量:
- 默认包含qt与C++版本
- release:构建Release版本;
- debug: 构建Debug版本;
- debug_and_release:同时构建Release和Debug版本;
- warn_on:显示警告信息;
- warn_off:关闭警告信息。
- mainwindow.ui
UI设计界面,可以直接通过拖拽控件来设计UI界面,系统根据界面会自动生成xml文档,程序员很难手动修改值。
- mainwindow.h与mainwindow.cpp
- mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow; //根据ui文件生成的类,和下面的MainWindow不是一个类
}
class MainWindow : public QMainWindow
{
Q_OBJECT //添加QT对象属性的宏 要是继承QObject的类,必须调用这个宏
public:
explicit MainWindow(QWidget *parent = 0); //继承QObject的类 在构造函数中都要指定父节点参数 因为有父节点时对象才能被自动删除
~MainWindow();
private:
Ui::MainWindow *ui; //指向界面文件生成的UI对象的指针
};
#endif // MAINWINDOW_H
- mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), //初始化父类
ui(new Ui::MainWindow) //创建ui对象
{
ui->setupUi(this); //设置ui的父对象 让UI对象与当前的窗口产生关联
}
MainWindow::~MainWindow()
{
delete ui; //删除UI对象 因为UI对象没有继承QObject 并没有被QT管理
}
- main.cpp解读
#include "mainwindow.h"
#include <QApplication>
//QApplication管理了各种各样的应用程序的广泛资源,比如默认的字体和光标。
int main(int argc, char *argv[])
{
QApplication a(argc, argv); //a是这个程序的QApplication对象,必须创建,是该程序应用的对象。
MainWindow w; //创建一个窗口,默认是只创建不显示
w.show(); //将窗口显示出来
return a.exec(); //通过a对象执行程序
}
二、UI初识
- UI设计步骤
- 拖拽想要的控件至指定位置
- label标签控件:可以显示文本信息
- push_button:普通按钮
- 更改objectName,以供代码操作使用
- 在代码中使用ui指针找到指定控件的objectName并进行操作
- 添加信号和槽等候用户操作
- objectName的起名
使用 控件名_功能名 进行起名
例如:label_name,pushButton_submit等;
三、信号与槽(Signal & Slots)
- 信号与槽是QT提供的任意两个(QObject)对象之间的通信机制,常用来完成界面操作的响应。
- 信号:是可以看作是一个请求或者一个动作的标志。
- 槽:其实就是一个处理函数,是在对象中声明为slots:之下的函数及其实现,其类似于回调函数一样。槽是一个对象对他感兴趣的对象的某个时间做出处理。
- 其信号槽工作的过程是:当一个对象发射一个信号的时候,则和其连接的对象的槽函数进行处理,等槽函数处理完成之后退出并执行接下来的内容。
- 信号与槽的使用
connect(sender, SIGNAL(send()), receiver, SLOT(receive()))
- sender:发送信号的对象的指针
- send():sender对象发送的信号
- receiver:接收信号的槽对象的指针
- receive():receiver用来接收send()信号的槽函数
使用步骤:
- 创建一个函数作为槽函数(在声明处使用访问权限 slots:进行修饰),并完成实现
- 在槽函数中编写接到信号后的一系列处理(改文本等)
- 在MainWindow的构造函数中使用connect函数进行信号与槽的连接
- 依次在connect函数中 指定信号发送者,设定触发发送信号的方式,指定接收者,设定已定义好的槽函数
- 定义槽函数
访问权限 slots:
槽函数声明
private slots:
void change();
- 自定义信号
signals:
信号函数声明(信号函数不可以被实现)
- 发送信号
emit 信号函数
- 信号和槽的参数传递
- 当信号与槽函数的参数数量相同时,它们参数类型要完全一致。
- 当信号的参数与槽函数的参数数量不同时,只能是信号的参数数量多于槽函数的参数数量,且左边相同数量的参数类型应一致,信号中多余的参数会被忽略。
四、QT中的字符串操作(QString)
可以使用qDebug()进行输出测试,需导入<QDebug>头文件,用法与cout类似。
- 拼接
QString s1 = "hello ";
QString s2 = "world";
s1 += s2;
s1.append(" farsight");
- 格式化
s1.sprintf("%s %d","哈哈",100);
s1 = QString("%1 was born in %2").arg("小明").arg(1900);
- 移除空白字符
- 移除两端空白字符
s1 = " hello good farsight ";
s1 = s1.trimmed();
- 移除两端空白字符,使用单个空格代替字符串中间的空白字符
s1 = " hello good farsight ";
s1 = s1.simplified();
- 查询(Qt::CaseInsensitive大小写不敏感,Qt::CaseSensitive大小写敏感)
- 查询开头 大小写不敏感
QString s1 = "Welcome to you!";
qDebug()<<s1.startsWith("welcome", Qt::CaseInsensitive);
- 查询开头 参数2默认为大小写敏感
qDebug()<<s1.startsWith("welcome");
- 查询结尾
qDebug()<<s1.endsWith("you!", Qt::CaseSensitive);
- 包含 参数2默认为大小写敏感
qDebug()<<s1.contains("to");
mid 截取字符串
参数1为起始下标位置,参数2为截取个数
Split 根据所给字符串格式分割字符
分割结果为QStringList,可变历
- 其他操作
- insert() 在原字符串指定位置插入另一个字符串
- prepend() 在原字符串开头插入另一个字符串
- replace() 用指定的字符串替换原字符串中的某些字符
- 比较 > < >= <= ==
- 字符串转换 toInt() toDouble() toFloat() toLong() toLongLong()
五、QT常用widget与其常用成员函数
- widget通用属性
- enabled:控件是否有效(灰色状态)
- geometry:有x,y,宽度,高度属性,是窗口默认显示的坐标和大小 锚点
- minimumSize和maximumSize:设置窗口的最小和最大尺寸
- Palette为窗口样式,从窗口的文本颜色到激活非激活状态下窗口的显示方式都有,可以自行在设计师界面或者代码中调整
- font为字体菜单,选择窗口默认字体和大小
- cursor设置鼠标位于窗口中时的显示方式,包括默认状态,选中,等待等。
- 标签 Label
Label一般用于显示一个提示性的字符串,或者显示图片或电影
- void setText(QString); 设置label框内的文本
- void hide(); 隐藏label框
- void clear(); 清空label框内所有内容
- void setToolTip(QString); 设置信息提示
- void setToolTipDuration(int); 设置信息提示的持续时间,单位是毫秒
- void setAlignment(Qt::Alignment); 设置label框的对齐格式
- 单行输入框 LineEdit
LineEdit可以提供文本输入(单行)
- void setPlaceholderText(QString) 设置提示字
- void setText(QString) 设置编辑框内的文本
- void setReadOnly(bool) 把设置编辑框为只读模式,无法进行编辑.
- void setEnabled(bool) 设置是否激活行编辑框,作用和3类似
- bool isModified() 判断文本是否被修改
- QString displayText() 返回显示的文本
- QString selectedText() 返回被选中的文本
- QString text() 返回输入框的当前文本
- void setMaxLength(int) 设置文本的最大允许长度
- void setEchoMode(QLineEdit::模式) 设置文本显示模式,password为黑点
六、对话框(Dialog)
- 创建对话框
- 项目中新创建文档
- 选择模板为Dialog...
- 在槽函数中创建自定义对话框的对象,在堆空间中创建,可以依托于某个父组件
- 使用show函数显示
- 模态和非模态对话框
- 模态对话框:即在没有关闭之前,不能再与同一个应用程序的其它窗口进行交互,比如新建项目时弹出的对话框。
dialog->setModal(true);
- 非模态对话框:可以在同一程序中与他交互,如查找替换对话框,默认的对话框为非模态。
dialog->setModal(false);
- QT自带标准对话框
- 标准文件对话框 QFileDialog类
打开标准文件对话框并返回用户选中的文件
QString QFileDialog::getOpenFileName
(
QWidget* parent = 0, //标准文件对话框的父窗口
const QString& caption = QString(), //标准文件对话框的标题名
const QString& dir = QString(), //指定默认的目录,若此处有文件,则文件将是默认选中的文件
const QString& filter = QString(), //过滤器,名称+(),括号里是文件的过滤规则,如*.c,多过滤器之间用;;隔开,默认是无过滤
QString* selectFilter = QString(), //用户选中的参数4中的过滤器将通过参数5返回
Options option = 0 //选择显示文件名的格式,默认是显示目录和文件名
);
- 标准颜色对话框 QColorDialog类
QColor getColor
(
const QColor &initial = Qt::white, //默认选中的颜色
QWidget *parent = 0, //父窗口
const QString &title = QString(), //标题名
ColorDialogOptions options = 0 //参数
);
- 标准字体对话框 QFontDialog类
QFont getFont(
bool *ok, //用户是否选择确定
const QFont &initial, //默认字体
QWidget *parent = 0, //父窗口
const QString &title = QString(), //标题
FontDialogOptions options = 0 //参数
);
- 标准输入对话框 QInputDialog类
- 标准字符串输入对话框
QString getText(
QWidget *parent, //父窗口
const QString &title, //标题
const QString &label, //输入提示
QLineEdit::EchoMode echo = QLineEdit::Normal, //QLineEdit 输入模式
const QString &text = QString(), //QLineEdit 默认显示的内容
bool *ok = 0,
Qt::WindowFlags flags = 0, //窗口类型
Qt::InputMethodHints inputMethodHints = Qt::ImhNone //输入类型
);
- 标准条目选择对话框
QString getItem(
QWidget *parent,
const QString &title,
const QString &label,
const QStringList &items, //所有的条目
int current = 0, //默认显示的条目索引
bool editable = true, //条目是否可编辑
bool *ok = 0,
Qt::WindowFlags flags = 0,
Qt::InputMethodHints inputMethodHints = Qt::ImhNone
);
- 标准int类型输入对话框
int getInt(
QWidget *parent,
const QString &title,
const QString &label,
int value = 0, //默认显示值 QSpinBox
int minValue = -2147483647, //允许输入最小值
int maxValue = 2147483647, //允许输入最大值
int step = 1, //步进值
bool *ok = 0,
Qt::WindowFlags flags = 0
);
- 标准double类型输入对话框
double getDouble(
QWidget *parent,
const QString &title,
const QString &label,
double value = 0,
double minValue = -2147483647,
double maxValue = 2147483647,
int decimals = 1, //精度,小数点后保留位数
bool *ok = 0,
Qt::WindowFlags flags = 0
);
- 消息对话框 QMessageBox类
- Question消息框
int question(
QWidget *parent,
const QString &title,
const QString& text, //消息内容
StandardButton button0, //对话框包含的按钮
StandardButton button1 //默认焦点所在按钮
);
- infomation消息框
StandardButton information(
QWidget *parent,
const QString &title,
const QString& text,
StandardButton button0,
StandardButton button1 = NoButton
);
- Warning消息框
int warning(
QWidget *parent,
const QString &title,
const QString& text,
StandardButton button0,
StandardButton button1
);
- Critical消息框
int critical(
QWidget *parent,
const QString &title,
const QString& text,
StandardButton button0,
StandardButton button1
);
- About消息框
void about(
QWidget *parent,
const QString &title,
const QString &text
);
- AboutQt消息框
void aboutQt(
QWidget *parent,
const QString &title = QString()
);
7.自定义消息框
QMessageBox customMsg;
customMsg.addButton(); //添加按钮
customMsg.setWindowTitle(); //设置标题
customMsg.setText(); //设置消息内容
customMsg.setIconPixmap(); //设置显示图片
customMsg.exec(); //显示并执行消息框
customMsg.clickedButton(); //获得选中按钮的指针
七、主窗口
- QActon 动作类 菜单和工具栏内的具体条目,负责完成具体功能
- 构造函数
QAction(
const QIcon &icon, //图标
const QString &text, //名字
QObject* parent //父窗口
);
- 设置快捷键
void setShortcut(const QKeySequence &shortcut);//参数传递QString
- QMenu 菜单类
QMenuBar菜单栏类,窗口默认创建,调用主窗口函数QMenuBar *menuBar() const 获得当前窗口的QMenuBar对象
- 向QMenuBar对象添加菜单
QMenu *addMenu(const QString &title)
- 向菜单QMenu对象中添加QAction
void addAction(QAction *action)
- QToolBar 工具栏类
- QToolBar工具栏类:调用主窗口函数 QToolBar *addToolBar(const QString &title) 创建QToolBar对象
- 向QToolBar对象添加QAction对象 void addAction(QAction *action)
八、事件
- 鼠标事件
- 需导入头文件<QMouseEvent>
- 事件函数
- void mousePressEvent(QMouseEvent* e); //当鼠标按下
- void mouseReleaseEvent(QMouseEvent* e); //当鼠标释放
- void mouseMoveEvent(QMouseEvent* e); //当鼠标移动
- void mouseDoubleClickEvent(QMouseEvent* e); //当鼠标双击
- 实时跟踪鼠标移动的位置将QWidget::setMouseTracking(bool enable) 设置为true
- e的属性
- e.x()获取鼠标的x轴坐标
- e.y()获取鼠标的y轴坐标
- e.button()获取是哪个按键触发事件
- 键盘事件
- 需导入头文件<QKeyEvent>
- 事件函数
- void keyPressEvent(QKeyEvent* e); //当键盘中的某个键被按下
- 定时事件
- 需导入头文件<QTimerEvent>
- 事件函数
- void timerEvent(QTimerEvent* e); //定时事件
- 启动定时器
int startTimer( //返回值定时器id
int interval, //定时器时间,默认为毫秒
Qt::TimerType timerType = Qt::CoarseTimer //定时器精度
);
- 暂停定时器
void killTimer(int id); //停止指定id的定时器
九、文件
- QFile读写文本文件
- 创建对象QFile(const QString &name);
- 打开文件bool open(OpenMode flags);
- ReadOnly
- WriteOnly
- ReadWrite
- Append
- Truncate
- 写文件qint64 write(const char *data, qint64 len);
- 读文件qint64 read(char *data, qint64 maxlen);
- 复制文件 bool copy(const QString &newFile);
- 字符流,适合操作纯文本文件,传输以字符为单位,速度相对较快
- 创建对象explicit QTextStream(QIODevice *device);
- 读文件QTextStream &operator>>(QString &s);
- 写文件QTextStream &operator<<(const QString &s);
- 格式化函数
qSetFieldWidth(int width) 设置字段宽度
qSetPadChar(QChar ch) 设置填充字符
qSetRealNumberPercision(int precision) 设置实数精度
- 流操作符
- bin 设置读写的整数为二进制
- oct 设置读写的整数为八进制
- dec 设置读写的整数为十进制
- hex 设置读写的整数为十六进制
- showbase 强制显示进制前缀
- forcesign 强制显示符号 + -
- forcepoint 强制显示小数点
- noshowbase 不显示进制前缀
- noforcesign 不显示符号
- left 居左
- right 居右
- center 居中
- endl 换行
- flush 清理缓存
- 字节流,适合操作非纯文本文件,传输以字节为单位,速度相对较慢
- 创建对象 explicit QDataStream(QIODevice *);
- 读文件 QDataStream &operator>>(char *&str);
- 写文件 QDataStream &operator<<(const char *str);
- QDir 目录操作
- 创建对象 QDir(const QString &path = QString());
- 查找目录内的子元素 QStringList entryList(Filters filters = NoFilter, SortFlags sort = NoSort) const;
- 参数1:过滤器
- QDir::Dirs 按照过滤方式列出所有目录
- QDir::AllDirs 不考虑过滤方式列出所有目录
- QDir::Files 所有文件
- QDir::Drives 所有磁盘驱动器(UNIX系统无效)
- QDir::Hidden 所有隐藏文件
- 参数2:排序规则
- QDir::Name 按照名字排序
- QDir::Time 按照修改时间排序
- QDir::Size 按照文件大小排序
- QDir::Type 按照文件类型排序
- QDir::DirsFirst 目录优先排序
- QDir::DirsLast 目录最后排序
- QDir::Reversed 反序
- QDir::IgnoreCase 忽略大小写方式排序
- QDir::LocaleAware 使用当前本地排序方式排序
- QFileInfo 文件信息类
- 创建对象QFileInfo(const QString &file); 参数要求是文件的绝对路径+文件名
- 获得各种信息
- QDateTime created() const; 获得创建时间
- qint64 size() const; 获得文件大小
- bool isFile() const; 判断是否为文件
- bool isDir() const; 判断是否是目录
- bool isReadable() const; 是否可读
- bool isWritable() const; 是否可写
- bool isExecutable() const; 是否可执行
十、数据库操作
QT += sql
- QSqlDatabase数据库连接对象
- 添加数据库驱动,创建数据库连接
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
- 设置主机名
db.setHostName(主机名);
- 设置数据库名,sqlite产生的文件名
db.setDatabaseName(数据库名.db);
- 打开数据库
db.open();
- 关闭数据库
db.close();
- QSqlQuery数据库操作对象
- 通用操作
- 创建数据库操作对象
QSqlQuery query
- 预设要执行的sql语句,需要传参的位置用?占位
query.prepare(sql语句);
- 为设定好的sql语句传入具体参数,参数位置与具体值
query.bindValue(位置,值);
- 执行sql语句,返回执行是否成功
query.exec();
- 增 删 改
- Sql语句复习
- 实现步骤
QSqlQuery query;
query.prepare("insert into persons(name) values(?)");
query.bindValue(0,"张三");
return query.exec();
- 查
- Sql语句复习
- query.next()
判断查询结果中是否有下一条,有则返回true并指向下一行,没有则返回false
- query.record()
获取查询记录,并通过调用value()函数获得记录中的字段值
- 实现步骤
QSqlQuery query;
vector<Person> persons;
query.prepare("select * from person where age between ? and ?");
query.bindValue(0,20);
query.bindValue(1,30);
bool ok = query.exec();
while(query.next())
{
Person p(
query.record().value("name").toString(),
query.record().value("id").toInt(),
);
persons.push_back(p);
}
return ok;
十一、线程
- 线程使用
- 定义线程类继承QThread,
- 重写run函数,在run函数中编写线程要执行的逻辑
- 在run函数中通过自定义信号发送消息至主窗口
- 由窗口类编写的槽函数接收并处理信号
- 启动和停止线程,start() terminate()
- 互斥锁 QMutex类
在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步。
线程互斥锁是实现线程同步的一种办法,在一个线程修改变量时加锁,则其他变量阻塞,等待加锁的变量解锁后再执行。
创建QMutex类对象
- 在线程需要改变变量前使用QMutex类对象.lock()加锁
- 在修改之后QMutex类对象.unlock();解锁
注意:必须解锁,不然则会发生死锁现象,线程无法继续
十二、网络编程
QT += network
- TCP
- TCP服务端
#include <QTcpServer>
#include <QTcpSocket>
- 创建QTcpServer对象
- 为服务设置监听方式(listen)与端口
- 连接新客户端的连接信号 SIGNAL(newConnection())
- 在槽函数中获取新连接过来的客户端套接字对象 client = server->nextPendingConnection();
- 读取客户端发来的消息:
- 将客户端连接 预备读取 信号 SIGNAL(readyRead())
- 通过客户端对象调用readAll()函数读取所有客户端发送过来的消息
- 向客户端发送消息:
- 调用客户端.write函数,将要发送的消息转成char类型发送,toLocal8Bit转为char类型client->write(data.toLocal8Bit().data(), data.toLocal8Bit().size())
- 断开连接:
- 为客户端连接disconnect信号
- TCP客户端
#include <QTcpSocket>
#include <QHostAddress>
- 创建QTcpSocket对象
- 使用socket对象调用connectToHost函数设置连接主机IP、端口与权限
- socket连接 连接信号 connected
- 当连接上信号时(调用到connected信号的槽函数时),连接断连信号和预备读取信号
- UDP
#include <QUdpSocket>
#include <QHostAddress>
- 创建QUdpSocket对象
- 绑定监听端口
- 连接接受到消息时执行的槽函数
- 发送数据
qint64 writeDatagram(
const QByteArray &datagram, //发送的数据 可以使用QString进行转换
const QHostAddress &host, //接收端服务器的类型
quint16 port //接收端端口号
);
- 接收数据
qint64 readDatagram(
char *data, //读取数据到data中
qint64 maxlen, //最大长度
QHostAddress *host = 0, //发送广播的主机
quint16 *port = 0 //端口
);
示例:读取数据
while(socket->hasPendingDatagrams())//判断socket是否有数据报 可读
{
QByteArray data;
data.resize(socket->pendingDatagramSize());
socket->readDatagram(data.data(), data.size());
ui->lineEdit->setText(QString::fromLocal8Bit(data));
}