qt学习笔记


使用建议:建议使用 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();








   

你可能感兴趣的:(qt,c,linux)