使用建议:建议使用 gedit 软件查看本笔记,可以让代码中的关键字、注释等高亮显示,增强可读性;
另外建议把 gedit 软件首选项里的制表位设置为 4(默认为 8),代码中的缩进就会更合理;字体建议用 13 号。
《目录》
DAY01---qt 安装,qt 编程环境,中文乱码问题(QLabel),按钮类,父窗口,滑块/微调框
DAY02---输入框,加法器,自定义信号/槽函数,设计器,使用 ui 文件
DAY03---QtCreator,
*****************************************************
DAY01-GUO
1. QT 简介:
基于 c++ 语言的框架(框架:软件半成品),专注于图形用户界面 GUI,
跨平台(unix, linux, mac, windows, 嵌入式),开源,免费的图形工具;
QT 安装过程:
首先准备 qt 安装包,里面有 CentOS5-Base-163.repo 文件;然后执行下面命令:
/* 删除机器里原有的 yum.repos 文件夹里的内容,为下面更新清空环境;*/
$ rm -f /etc/yum.repos/*
/* 下面的步骤需要 root 权限,进入 root:*/
$ su
/* 输入口令:(这里用的是 tarena 的口令)*/
口令:xATarena2013
/* 进入到 qt 安装包,然后把下载到的 CentOS5-Base-163.repo 文件拷到 etc 目录下,并命名为 yum.repos.d */
# cp -f CentOS5-Base-163.repo /etc/yum.repos.d
/* 执行 yum 升级命令 */
# yum install libXtst-devel libXext-devel libX11-devel
/* 升级完了,在进入到 qt 安装包,继续执行下面命令:*/
# ./configure
/* 然后会出现命令提示符,需要作选择:*/
o
/* 继续选择:(大约需要十分钟来执行更新)*/
yes
/* 继续执行下面代码:(大约需要两个小时来执行更新)*/
# gmake
# gmake install
在 root 权限下,依次执行下面步骤:
/* 找到 Qt-4.5.3 所在目录:*/
# find / -name Qt-4.5.3
/* 得到如下结果:*/
/usr/local/Trolltech/Qt-4.5.3
/* 进入根目录,修改环境变量:*/
# cd ~/
# vi .bashrc
/* 在里面加入以下代码 */
export PATH=$PATH:/usr/local/Trolltech/Qt-4.5.3
export PATH=$PATH:/usr/local/Trolltech/Qt-4.5.3/include
export PATH=$PATH:/usr/local/Trolltech/Qt-4.5.3/lib
export PATH=$PATH:/usr/local/Trolltech/Qt-4.5.3/bin
/* 保存退出,并执行下面代码:*/
# source .bashrc
/* 测试安装情况:*/
# qmake -version
/* 输出如下内容:*/
QMake version 2.01a
Using Qt version 4.5.3 in /usr/local/Trolltech/Qt-4.5.3/lib
/* 最后,在自己的用户下,再把上面的环境变量配置一遍就可以了;*/
/* 至此,大功告成!*/
2. qt 编程环境
1)qt 安装目录:
$ cd usr/bin /* 默认路径 */
$ ls ass*
assistant /* 帮助文档 */
$ assistant /* 打开帮助文档 */
帮助文档的作用:
a. 查看模块名:
b. 继承关系;
c. 类属性;
d. 类函数;
构造等;
e. 槽 slots(一种特殊函数)
public slots:
void testslot();
f. 信号 signals(也是一种特殊函数,和 UC 里的不一样)
public: signals: /* 两个冒号 */
void mysig(); /* 信号函数只需要声明,实现部分由系统自动完成;*/
g. 静态成员;
静态成员变量;
静态函数(不用创建对象就可以调用);
h. 保护函数;
一般是留给子类覆盖用,属于扩展功能;
i. 元数据(类似原 c 的宏)
Q_OBJECT / SLOT / SIGNAL
j. 类的详细描述;
2)qt 编程工具:
$ designer 所见即所得界面设计器,得到的文件扩展名为 .ui
$ qmake -version 得到 qt 版本信息;
$ qmake -project 把项目源代码组织成项目描述文件;扩展名为 .pro
$ qmake 根据 pro 文件得到 Makefile(文件依赖)
$ make 根据 Makefile 得到目标文件(可执行文件/库文件 . . . )
$ qtcreator qt 集成开发工具,集成了上面所有工具;
3)qt 头文件:
安装路径:/usr/include/qt4
按照功能划分模块:
QtCore
QtGui
QtSql
QtNetWork
QtOpenGL
QtXml
一个功能对应一个类,一个类对应一个头文件;
标准的 c++ 没有 .h 头文件;但是 qt 提供两套头文件,分别给 c 和 c++ 调用;
qt 库文件:对头文件的分模块实现;
目录:/usr/lib/i386-linux-gnu
任何一个 qt 程序都会成为一个工程,一般我们要单建一个文件夹,一般文件夹名和文件名一样;
如果不一样,程序会警告,但是不影响执行;
qt 程序以 .cpp 为扩展名;
例 1:先创建一个 first 文件夹,然后在里面创建 first.cpp 文件;
#include /* 应用类 */
#include /* 标签类 */
int main(int argc, char** argv) { /* 需要命令行参数,构建对象的时候需要用;*/
QApplication app(argc, argv); /* 构建 qt 应用程序对象;*/
QLabel qlab("hello QT."); /* 构建标签对象,默认隐藏;*/
qlab.show(); /* 让标签对象显示;*/
return app.exec(); /* 让程序进入事件循环;否则界面会一闪而过;*/
}
执行顺序:
首先,进入 first 文件夹;然后依次执行下面代码:
$ qmake -project => first.pro
$ qmake => Makefile
$ make => first.o 和 first
如果文件夹名和文件名不一样
运行会报错,但是不影响程序的执行;
3. 中文乱码问题
例:把上面的例题稍作改动:
#include
#include
int main(int argc, char** argv) {
QApplication app(argc, argv);
QLabel qlab("你好 QT."); /* 仅仅改变这里输出内容 */
qlab.show();
return app.exec();
}
运行会出现中文乱码问题,解决办法:
1)首先引进 QObject 类和文本编码类 QTextCodec:
#include /* 对象类 */
#include /* 文本编码类 */
2)根据编码方式得到编码对象:
QTextCode* coder = QTextCodec::codecForName(" 编码方式 "); /* 和本机 shell 终端编码保持一致 */
3)设置编码对象:
QtextCodec::setCodeForTr(coder);
4)对字符串进行翻译:
QObject::tr(" 字符串 ", " 编码 ");
常见编码:utf-8, GBK, gb2312
#include
#include
#include /* 对象类 */
#include /* 文本编码类 */
int main(int argc, char** argv) {
QApplication app(argc, argv);
/* 得到编码对象 */
QTextCode* coder = QTextCodec::codecForName("utf-8");
/* 设置编码对象 */
QtextCodec::setCodeForTr(coder);
/* 构建标签 */
QLabel qlab(QObject::tr("你好 QT.", "utf-8"));
qlab.show();
return app.exec();
}
4. 按钮类
一个对象的动作(函数),会影响到另一个对象;
我们引入按钮类(QPushButton),来作实验,利用 QObject 中的 connect() 函数把两者联系起来:
QObject::connect(const QObject* sender, const char* signal,
const QObject* receiver, const char* method);
sender:信号发送者指针;
signal:发出的信号,在 qt 里,信号就是函数,函数是地址,地址本质上是整数;需要把整数转为 char*;
SIGNAL(test()); /* 系统自动把地址转为 char* 类型 */
receiver:信号接收者指针;
method:槽函数,是一个指针/地址,也需要类型转换;
SLOT(gg()); /* 系统自动把地址转为 char* 类型 */
当 sender 发出相应的 signal 信号时,对象 receiver 就会调用相应的 method;
下一步可以通过帮助文档,查询 QPushButton 里的 signal 信号函数;(如果没有,就找其父类)
void clicked(); /* 默认无参 */
最后查找 QLabel 里的槽函数 Slots(和信号函数相对应)
bool close(); /* 关闭 */
void hide(); /* 隐藏 */
槽函数完全可以像一个普通成员函数那样去调用;
当我们查文档的时候,如果普通函数都没有符合要求的,我们可以看看槽函数;
在不用信号传递的时候,槽函数就相当于普通函数;
信号和槽函数连接的时候,必须保证参数类型,个数,顺序等都相同;
如果参数有默认值,则可以认为参数不存在;
如果想让任何信号和槽函数连接,那么可以通过自定义信号或者槽函数间接连接;(第二天具体讲)
例 1:点击按钮,关闭标签
#include
#include
#include /* 按钮类 */
int mian(int argc, char** argv) {
QApplication app(argc, argv);
QLabel qlab("hello"); /* 栈方式创建标签 */
qlab.show();
/* 堆方式创建按钮,目前无法释放内存,以后学;也可以使用上面栈方式创建; */
QPushButton *qpush = new QPushButton("close");
qpush->show();
/* 下面实现功能部分,点击按钮,关闭标签:*/
QObject::connect(qpush, SIGNAL(clicked()), &qlab, SLOT(close()));
return app.exec();
}
运行后,会出现两个窗口,一个 lab,一个按钮,点击按钮,关闭 lab 窗口;
qt 的信号和槽机制是 qt 的核心特性;可以关联两个毫不相干的对象;
关联一个对象的信号到另一个对象的槽;
例 2:点击按钮,关联到 app,关闭 app 同时关闭按钮;
#include
#include
#include
int mian(int argc, char** argv) {
QApplication app(argc, argv);
QLabel qlab("hello");
qlab.show();
QPushButton *qpush = new QPushButton("close");
qpush->show();
/* 下面实现功能部分,点击按钮,退出应用文件;*/
QObject::connect(qpush, SIGNAL(clicked()), &app, SLOT(quit())); /* 退出应用程序用 quit() */
return app.exec();
}
5. 父窗口
如果一个窗体没有父窗口,则这个窗体是一个独立窗体;
如果一个窗体指定了父窗口,则这个窗体就会停靠在父窗口上;
父窗体的类型必须是 QWidget 类型或者其子类型(QMainWindow/QDialog);
创建组件:
QWidget* parentw = new QWidget();
QLabel qlab("hello", parent);
QPushButton qpush("close", parent);
改变组件大小:
resize(x, y);
改变组件位置:
move(x, y);
例:让两个窗体位于一个窗体里;
#include
#include
#include
#include /* 小窗口类 */
int main(int argc, char** argv) {
QApplication app(argc, argv);
/* 做一个父窗口 */
QWidget* parentw = new QWidget();
QLabel qlab("hello", parentw); /* 指定父窗口 */
QPushButton qpush("close", parentw); /* 指定父窗口 */
parentw->shwo(); /* 父窗口 show,子类就不用再 show 了;*/
return app.exec();
}
本程序执行后,qlab 和 qpush 两个窗体会互相覆盖;
那么我们需要调整窗体大小:
resize(x y); /* 如果屏幕是 1024*768,那么 x<=1024, y<=768 */
同时移动窗体位置:
move(x, y); /* 参数同上 */
程序修改如下:
#include
#include
#include
#include
#include
int main(int argc, char** argv) {
QApplication app(argc, argv);
/* 做一个父窗口 */
QWidget* parentw = new QWidget();
parentw->resize(500, 400); /* 指定父窗口大小,差不多有屏幕一半大;*/
QLabel qlab("hello", parentw); /* 标签还是默认在父窗口左上角的位置;*/
QPushButton qpush("close", parentw);
qpush.move(200, 300); /* 按钮的位置是相对于父窗口而言的;*/
parentw->show();
/* 下面实现功能部分,点击按钮,关闭父窗口(子窗口也被关闭);*/
QObject::connect(qpush, SIGNAL(clicked()), parentw, SLOT(close())); /* 关闭窗口用 close() */
return app.exec();
}
6. QSlider 滑块类 和 QSpinBox 微调框类 的信号函数和槽函数可以公用:
信号函数:
void sliderMoved(int value);
void valueChanged(int val);
槽函数:
void setValue(int val);
注意:当连接的信号和槽中有参数时,在 SIGNAL 和 SLOT 中只能出现参数类型,除非参数有默认值:
例:利用滑块和微调框互相影响;
#include
#include
#include
#include
#include
int main(int argc, char** argv) {
QApplication app(argc, argv);
/* 只声明,不实现;*/
QDialog* parent;
QSlider* qsli;
QSpinBox* qspin;
/* 在这初始化 */
parent = new QDialog();
parent->resize(600, 300);
qsli = new QSlider(parent);
qspin = new QSpinBox(parent);
/* 调整大小和位置 */
qsli->move(50, 50);
qspin->move(300, 200);
qsli->resize(20, 200);
qspin->resize(80, 40);
/* 让滑块滑动影响微调框数值 */
qspin->setValue(98); /* 设置微调框最大值为 98(系统默认最大为 99) */
/* 这里参数里只能写 int,不能写其他;*/
QObject::connect(qsli, SIGNAL(valueChanged(int)), qspin, SLOT(setValue(int)));
/* 让微调框影响滑块 */
QObject::connect(qspin, SIGNAL(valueChanged(int)), qsli, SLOT(setValue(int)));
/* 显示 */
parent->show();
return app.exec();
}
**************************************************************
DAY02-GUO
1. QLineEdit 输入框
例:模拟 qq 登录框;
#include
#include
#include
#include
#include
int main(int argc, char** argv) {
QApplication app(argc, argv);
QDialog *parent;
QLineEdit *uname;
QLineEdit *upasswd;
QPushButton *login;
QPushButton *cancel;
parent = new QDialog();
parent->resize(400, 300);
uname = new QLineEdit(parent);
upasswd = new QLineEdit(parent);
login = new QPushButton("login", parent);
cancel = new QPushButton("cancel", parent);
uname->move(200, 50);
upasswd->move(200, 100);
login->move(50, 250);
cancel->move(250, 250);
parent->show();
/* 实现功能,目前我们只能实现取消功能 */
QObject::connect(cancel, SIGNAL(clicked()), parent, SLOT(close()));
return app.exec();
}
登录按钮不能连接到父窗口,因为父窗口没有相应的槽函数来处理登录逻辑;
如果整个程序测试都通过,但是运行的时候出现连接错误,说明是之前的错误影响到现在的程序;
解决办法:删除所有后生成的文件,只保留源文件,重新编译运行。
2. 加法器
加法器:由于 qt 没有专门的加法类,所以我们需要自己写加法类;
如果不把加法器做成自己的类,则没有相应的槽函数处理计算功能;
注意事项:
1)类还是要作为父窗体,管理子窗体;
public QDialog {}
2)父窗体里面的所有组件作为父窗体类的成员变量,可以通过 this 指针来指向父窗体;
3)如果使用 c++ 方式写 qt 代码,类的头文件和实现文件需要分离开写(分离写不代表要写在两个文件里);
4)如果类中有自定义的信号或者槽函数,则需要类的头文件中加一个宏 Q_OBJECT;(如果没这个宏,信号和槽函数无法使用)
例 1:实现加法器功能;
首先编写头文件:adder.h
#ifndef ADDER_H
#define ADDER_H
#include
#include
#include
#include
class Adder : public QDialog { /* 继承自父窗口 */
private:
Q_OBJECT; /* 定义宏,给下面槽函数调用 */
QLineEdit *add; /* 加号前面那个数 */
QLabel *oper; /* 加号 */
QLineEdit *added; /* 加号后面那个数 */
QPushButton *equ; /* 等号 */
QLineEdit *res; /* 结果 */
public:
Adder();
~Adder();
/* 自定义槽函数,实现计算功能:*/
public slots: /* 修饰词,告诉我们下面的函数是槽函数;*/
void getRes();
};
#endif /* ADDER_H */
实现部分:adder.cpp
#include "adder.h"
Adder::Adder() {
this->resize(700, 300); /* this 代表父窗口 */
add = new QLineEdit(this);
oper = new QLabel("+", this);
added = new QLineEdit(this);
equ = new QPushButton("=", this);
res = new QLineEdit(this);
add->move(20, 150);
oper->move(190, 150);
added->move(220, 150);
equ->move(390, 150);
res->move(480, 150);
/* 连接功能,前面可以不加 Object::,因为其他类都继承自 Object */
connect(equ, SIGNAL(clicked()), this, SLOT(getRes()));
}
Adder::~Adder() {
delete add;
/* add = NULL; (qt 里可以不用这句代码)*/
delete oper;
delete added;
delete equ;
delete res;
}
void Adder::getRes() {
qDebug("this is complete caculater"); /* 用于测试,如果关联成功,会输出这句话;*/
/* 得到文本内容,用 text(),得到字符串类型:*/
QString qadd = add->text();
QString qadded = added->text();
/* 用 toInt() 把字符串转为 int 类型:*/
int iadd = qadd.toInt();
int iadded = qadded.toInt();
int ires = iadd + iadded;
/* 在把得到的 int 类型结果转为字符串输出:*/
res->setText(QString::number(ires));
/* 上面代码可以写为一行:
res->setText(QString::number(add->text().toInt() + added->text().toInt()));
*/
}
测试部分:testadder.cpp
#include
#include "adder.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
Adder adder;
adder.show();
return app.exec();
}
3. 信号和槽函数连接的时候,必须保证参数类型,个数,顺序等都相同;
如果参数有默认值,则可以认为参数不存在;
由于有上面的条件限制,所以并不是所有的信号和槽函数都能直接进行连接;
如果想让任何信号和槽函数连接,那么可以通过自定义信号或者槽函数间接连接;
1)自定义槽函数,和无参信号函数匹配:
例:点击按钮,得到当前时间;
头文件:gettime.h
#ifndef GETTIME_H
#define GETTIME_H
#include
#include
#include
class GetTime : public QDialog { /* 自定义类名尽量用大写,防止与系统函数冲突;*/
private:
Q_OBJECT;
QLabel *timeres;
QPushButton * gettime;
public:
GetTime();
~GetTime();
public slots:
void setTime();
};
#endif /* GETTIME_H */
实现:gettime.cpp
#include "gettime.h"
#include
GetTime::GetTime() {
this->resize(400, 500);
timeres = new QLabel("current time is:", this);
gettime = new QPushButton("gettime", this);
timeres->move(150, 50);
gettime->move(150, 400);
/* 自定义槽函数,间接和 clicked() 无参信号匹配:*/
connect(gettime, SIGNAL(clicked()), this, SLOT(setTime()));
}
GetTime::~GetTime() {
delete timeres;
delete gettime;
}
void GetTime::setTime() {
QString timestr = QTime::currentTime().toString("hh:mm:ss");
timeres->setText(timestr);
}
测试:text.cpp
#include
#include "gettime.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
GetTime gettime;
gettime.show();
return app.exec();
}
2)自定义信号函数和槽函数:
例:上面程序修改如下:
头文件:gettime.h
#ifndef GETTIME_H
#define GETTIME_H
#include
#include
#include
class GetTime : public QDialog {
private:
Q_OBJECT;
QLabel *timeres;
QPushButton * gettime;
public:
GetTime();
~GetTime();
public slots:
void setTime();
public:signals: /* 注意是双冒号,只需要定义,无须实现;*/
void mySig(QString data);
};
#endif /* GETTIME_H */
实现:gettime.cpp
#include "gettime.h"
#include
GetTime::GetTime() {
this->resize(400, 500);
timeres = new QLabel("current time is:", this);
gettime = new QPushButton("gettime", this);
timeres->move(150, 50);
gettime->move(150, 400);
/* 第一步:关联自定义槽函数;setTime() */
connect(gettime, SIGNAL(clicked()), this, SLOT(setTime()));
/* 第三步:连接自定义信号和目标槽函数:*/
connect(this, SIGNAL(mySig(QString)), timeres, SLOT(setText(QString)));
}
GetTime::~GetTime() {
delete timeres;
delete gettime;
}
void GetTime::setTime() {
QString timestr = QTime::currentTime().toString("hh:mm:ss");
/* 有时候 timeres 不方便直接访问 setText(),所以需要自定义信号:
timeres->setText(timestr);
*/
/* 第二步:在槽函数里发射一个信号给目标槽函数:setText(QString) */
emit mySig(timestr); /* 注意:前面要加 emit */
}
测试:text.cpp
#include
#include "gettime.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
GetTime gettime;
gettime.show();
return app.exec();
}
4. 设计器:
$ designer /* 打开设计器 */
进入界面后,键盘使用:
方向键:可以调整组件位置,一次移动 10 像素;
ctrl+方向建:一次移动 1 像素;
shift+方向建:调整组件大小,一次调整 10 像素;
ctrl+shift+方向建:微调组件大小,一次 1 像素;
ctrl+i:属性对话框;
通过设计器设计出 ui 界面文件;
5. 使用 ui 文件
uic:把 ui 文件转换成 .h 文件;
举例:我们对上面加法器作修改;
先用设计器设计好加法器界面:adder_ui.ui,然后开始转换:
步骤:
1)首先进入到 adder_ui.ui 所在文件夹,然后执行下面命令:
$ uic adder_ui.ui -o adder_ui.h ==> adder_ui.h
(adder_ui.h 就是代表界面的文件)
2)把 adder_ui.h 拷贝进 adder 文件夹;
同时把原头文件 adder.h 内容改为:
#ifndef ADDER_H
#define ADDER_H
/* 引入界面文件 */
#include "adder_ui.h"
class Adder : public QDialog {
private:
Q_OBJECT;
/* 和界面相关的声明只需要换为下面这一句代码:*/
Ui_Dialog *ui; /* Ui_Dialog 这个名字可能变化,根据 adder_ui.h 里面的类名确定,和类名相同;*/
public:
Adder();
~Adder();
public slots:
void getRes();
};
#endif /* ADDER_H */
实现部分:adder.cpp
#include "adder.h"
Adder::Adder() {
/* 和界面相关的定义大小位置等都可以省略,只需要下面两步:*/
/* 第一步:制造界面;*/
ui = new Ui_Dialog();
/* 第二步:加载界面;*/
ui->setupUi(this); /* setupUi() 函数位于 adder_ui.h 里面;*/
/* 要访问界面对象,都要通过 ui */
connect(ui->equ, SIGNAL(clicked()), this, SLOT(getRes()));
}
Adder::~Adder() {
/* 仅需要析构一个 ui 即可:*/
delete ui;
}
void Adder::getRes() {
ui->res->setText(QString::number(ui->add->text().toInt() + ui->added->text().toInt()));
}
测试部分:testadder.cpp
#include
#include "adder.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
Adder adder;
adder.show();
return app.exec();
}
练习:改写 qq 登录框;
头文件 qqlogin.h
#ifndef QQLOGIN_H
#define QQLOGIN_H
#include "qqlogin_ui.h"
class QqLogin : public QDialog {
private:
Q_OBJECT;
Ui_Dialog *ui;
public:
QqLogin();
~QqLogin();
/* 槽函数既负责登录又负责退出:*/
public slots:
void LoginAndCancel();
};
#endif /* QQLOGIN_H */
实现文件 qqlogin.cpp
#include "qqlogin.h"
#include /* 消息框 */
QqLogin::QqLogin() : ui(new Ui_Dialog()) {
// ui = new Ui_Dialog();
ui->setupUi(this);
connect(ui->login, SIGNAL(clicked()), this, SLOT(LoginAndCancel()));
connect(ui->cancel, SIGNAL(clicked()), this, SLOT(LoginAndCancel()));
}
QqLogin::~QqLogin() {
delete ui;
}
void QqLogin::LoginAndCancel() {
/* 按钮判断 */
if (((QPushButton*)sender())->objectName() == "login") {
/* 用户名密码判断 */
if (ui->uname->text() == "abc" && ui->upasswd->text() == "123") /* 等于号在 c++ 里可以使用 */
qDebug("login success!");
}
if (((QPushButton*)sender())->objectName() == "cancel") {
/* 如果点击退出,就会弹出消息框提示:*/
QMessageBox msg;
msg.setText("are you sure to quit?");
/* 默认弹出消息框只有一个按钮,我们需要两个按钮:*/
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
if (msg.exec() == QMessageBox::Yes)
this->close();
}
}
测试文件:
#include "qqlogin.h"
#include
int main(int argc, char** argv) {
QApplication app(argc, argv);
QqLogin qq;
qq.show();
return app.exec();
}
************************************************************
DAY03-GUO
1. qtcreator 的使用步骤
1)新建 Qt4 Gui Application
2)在 Class Information 里修改 Class name 和 Base class
3)创建成功;
2. 设置快捷键
Tools->Options->Evironment->Keybord
在 filter 里输入 comp
在弹出对话框里选择 TextEditor.CompleteThis,修改快捷键为 ctrl+/
3. 添加图片
在根文件名上右击,选择 Add New->Qt Resource file
输入文件名,其他默认;进入界面 xxx.qrc:
/* 创建 .qrc 文件 */
Add->prefix
/* 把文件 Prefix 存放目录改为根目录 */
/new/prefix1 ==> /
/* 加入图片文件 */
Add->files
4. 定时器
QTimer 可以定时发出 timeout() 信号
绘制事件处理函数;void paintEvent(QPaintEvent *);
repaint();调用绘制事件处理函数;
定时器事件处理函数;void timerEvent(QTimerEvent *);
鼠标事件处理函数;void mousePressEvent(QMouseEvent *e);
键盘事件处理函数;void keyPressEvent(QKeyEvent *e);
举例:通过 qtcreator 设计,在头文件里对鼠标和键盘事件函数进行声明,然后在实现文件里代码如下:
/* 自定义鼠标事件:*/
#include
#include
void Mouse::mousePressEvent(QMouseEvent *e) {
QPoint qp = QCursor::pos(); // 得到光标的位置;
switch (e->button()) {
case Qt::LeftButton:
qDebug("left button clicked %d:%d", e->x(), e->y()); // 得到鼠标位置
qDebug("cursor %d:%d", qp.x(), qp.y());
break;
case Qt::RightButton:
qDebug("right button clicked %d:%d", e->x(), e->y());
qDebug("cursor %d:%d", qp.x(), qp.y());
break;
case Qt::MidButton:
qDebug("middle button clicked %d:%d", e->x(), e->y());
qDebug("cursor %d:%d", qp.x(), qp.y());
break;
}
}
/* 自定义键盘事件 */
#include
void Mouse::keyPressEvent(QKeyEvent *e) {
switch (e->key()) {
case Qt::Key_Left:
qDebug("left key pressed");
break;
case Qt::Key_Down:
qDebug("down key pressed");
break;
case Qt::Key_Right:
qDebug("right key pressed");
break;
case Qt::Key_Up:
qDebug("up key pressed");
break;
}
}
5. 贪吃蛇
基本元素:
食物----QLabel* /* 动态产生 */
蛇-----QList
方向----枚举;
步长----int
定时器---定时器事件处理(定时处理)
最大长度--int
功能:
控制蛇方向---键盘事件处理函数
控制蛇移动---槽函数
产生新的食物
********************************************************
1. 客户端的读取部分:
1)把变化的文件变成不变的;
2)读取上一次没有匹配的登入记录;
3)读取不变的日志文件;
结构体/STL
4)匹配日志记录,得到匹配集合;
5)把没有匹配的记录存入文件;
2. 定时执行任务:
$ crontab -e
* * * * * /home/tarena/c++/hello/a.out
第 1 颗星 分钟 0-59
第 2 颗星 小时 0-23
第 3 颗星 天(月) 1-31
第 4 颗星 月 1-12
第 5 颗星 天(周) 0-6
1,30 * 1-15 * 1-3 /home/tarena/c++/hello/a.out
意思:每周一到周三,每个月 1 到 15 号,每个小时的第 1 分钟和第 30 分钟。
如果要定时执行程序,执行程序的路径推荐采用绝对路径;
如果不写绝对路径,那么程序从主目录 /home/tarena/ 开始执行;
例如:
* * * * * /a.out
相当于:
* * * * * /home/tarena/a.out
$ crontab -r /* 清空 */
3. QThread
要实现线程功能就覆盖 run
void run();
要启动线程就调用 start
void start();