首页 > 代码库 > QT基础学习笔记

QT基础学习笔记

Qt简介:
1991, 挪威奇趣科技Trolltech开发的跨平台c++图形用户界面(GUI)应用程序开发。
2008,被诺基亚收购
2012,转让给芬兰的Digia公司。

商业版:专业版,企业版; // 开源版(GNU)

优势:
1.跨平台 2.面向对象 3.丰富API 类库  4.可视化编程 5,时间驱动机制

JAVA--compile once, run anywhere    一次编译,到处运行
Qt-- wrire once ,comile anywhere     一次编写,到处编译


桌面操作系统:Windows,   Mac OS X,   Linux/Unix X11
嵌入式操作系统:Windows CE, Sybian ,Meego,Embedded Linux


Qt 组成
QtSDK 4.7
 qmake编译器  moc 元对象编译器   uic 界面UI编译器   rcc 资源编译器   irelease/lupdata 翻译器 
Development Tools:
 QtCreator 2.4 跨平台轻量级IDE
 Qt Designer  拖拽式界面设计器
 Qt Linguist 预言家,翻译
 Qt Assistant Qt助手 帮助系统。

 

标准c++编译:.h+  .cpp ->.o -->.exe

元对象编译moc(meta-objects-compile):       .h+.cpp->.o -> exe
               meta-objects source files

Qt 编译 project sources +meta-objects+ ui:   .ui->.h+.cpp->.o -> exe
                       meta-objects source files

QT类库模块:
1.QtCore:Qt内核,IO,线程,容器类,IPC类
2.QtGui
3.QtOpenGl
4.QtNetwork
5.QtSql
6.Phonon
7.QtWebkit
8.QtXml

 

窗体基类:
1.QWidget:窗体基类
2.QMainWindow:主窗体基类(菜单 工具 工作区域 状态栏),继承于QWidget
3.QDialog:对话窗体基类,继承于QWidget


QObject 是qt绝大部分类的基类,一定是所有QWidget类的基类,包含:信号 槽  事件 属性 内存管理

Q_OBJECT:宏变量,使用moc(meta object compile原子对象编译),主要使用在信号与槽机制,必须写在类定义的最前面,而且必须是QObject的派生类

qt全局指针变量
qApp:A global pointer referring to the unique application object 指向应用程序对象的全局指针

qt全局命名空间
Qt:The Qt namespace contains miscellaneous identifiers used throughout the Qt library
包含QT枚举变量定义的命名空间


qt窗体关闭与系统推出关系:
1.关闭窗体 close
2.退出系统 quit
3.如果只打开一个窗体,关闭窗体同时也退出系统


Qt编程结构:
工程:.project

QT       += core gui

TARGET = qthello
TEMPLATE = app

头文件:HEADERS     .h
源文件:SOURCES:    .cpp
界面文件:FORMS     .ui  (会编译为头文件.h)
资源: RESOURCE  .qrc   

解决不能执行双击QT执行文件的问题:
1.修改环境变量path
2.path=path+C:\QtSDK\Desktop\Qt\4.8.1\mingw\bin


window平台下QT编译与链接命令
qmake
mingw

window cmd控制编译QT程序:(运行会出错)
1.qmake --project //生成工程文件
2.qmake -makefile  //生成makefile文件
3.mingw32-make     //链接生成exe文件
4.xx.exe

 

 一。简单窗口 Widget

widget.h //自定义窗口类的声明

#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QWidget>
#include <QtGui>  //包含所有窗体部件类
/*#include <QPushButton>
#include <QLineEdit>*/

class Widget : public QWidget
{
    Q_OBJECT  //宏变量,使用原子对象编译moc所需要的标记。
   
public:
    Widget(QWidget *parent = 0);
    ~Widget();
signals: //定义信号

public slots: //定义槽
    void setEditText();

private:
    QPushButton *btn; //按钮对象
    QLineEdit *edit;  //定义单行文本对象
};

#endif // WIDGET_H

widget.cpp    //自定义窗体类成员函数的实现

#include "widget.h"

Widget::Widget(QWidget *parent)   //构造
    : QWidget(parent)
{
 btn=new QPushButton(tr("按钮"),this);
      btn->setGeometry(100,100,30,20);//设置按钮,宽高度

 edit=new QLineEdit(this);
      edit->setGeometry(50,50,200,20);

     //链接信号与槽机制
     //SIGNAL:信号宏变量
     //SLOT:槽宏变量
    connect(btn,SIGNAL(clicked()),this,SLOT(setEditText()));
}

Widget::~Widget()   //析构
{
   
}

void Widget::setEditText()
{
    edit->setText("abcd"); //单行文本赋值
  
}

main.cpp//主函数实现

#include <QtGui/QApplication>
#include "widget.h"
#include <QTextCodec> //字符集类

int main(int argc, char *argv[])
{
    QApplication a(argc, argv); //应用程序类,主要是用来管理GUI应用程序
    //设置qt对于中文使用字符集(从本地机器获取)
    //tr:国际化函数
    QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
    Widget w; //定义窗体对象
    w.show();  //显示窗口
   
    return a.exec();  //让应用程序进入事件循环机制,响应执行用户事件(死循环)
}

 

qt信号与槽机制

信号与槽:实现原子对象对象之间通信
信号与槽使用的对象必须为QObject派生类,类中必须包含宏变量Q_OBJECT

什么是信号:
是一个无返回值不需要实现,没有访问权限限制(private public protected)的类的成员的函数
利用signals:关键说明
信号使用emit 发送信号


什么是槽:
槽是一个无返回值的成员函数,必须要实现函数


利用 connect实现信号与槽连接
connect(发送对象,SINGAL(信号),接收对象,SLOT(接收对象要执行动作))

信号与槽与注意事项
1.信号与槽不需要返回
2.信号不能直接调用,必须要emit函数发送,槽是可以当做一般函数调用
3.信号可以传递(信号自己不能发送给自己)
4.一个信号可以发送给多个接收对象(执行多个槽),但是槽执行的顺序是不确定
5.信号与槽可以有参数,参数不能是指针
  参数不能有默认值
  参数不能使模板类型

//自定义信号:
signals:
 void signal1();
 void signal2(QString str);
 void signal3(int a,int b);
//自定义槽(必须要说明访问权限)
public slots:
      void receiversignal1();
      void receiversignal2(QString str);
      void receiversignal3(int a);

 //连接信号与槽
connect(this,SIGNAL(signal1()),this,SLOT(receiversignal1()));
//发送对象与接收对象为同一个对象
connect(this,SIGNAL(signal2(QString)),SLOT(receiversignal2(QString)));
//接收对象的槽只能接收大于或等于槽参数个数的信号
connect(this,SIGNAL(signal2(QString)),SLOT(receiversignal1()));
//信号与槽参数个数可以不相等,但是对应参数数据类型要匹配
connect(this,SIGNAL(signal3(int,int)),SLOT(receiversignal3(int)));


//发送信号
emit signal1();
//发送有参数信号
emit  signal2("abc");
emit signal3(20,200);

 

事件QEvent
#include <QEvent>

事件是结合操作系统消息响应,能够让应用程序进入到操作系统的消息队列,可以通过捕捉用户的针对桌面程序动作,实现具体功能

qt事件的基类QEVENT
常见的事件:鼠标事件  键盘事件  关闭事件  绘画事件

如何实现事件:
1.创建对象的派生类,重写具体事件函数
2.在类中重写Event函数
3.利用事件过滤器

class QLineText : public QLineEdit
{
    //重写失去焦点和获得焦点事件
    //QFocusEvent * e:保存关于焦点事件的相关属性 函数等
    void focusInEvent(QFocusEvent * e);
    void focusOutEvent(QFocusEvent * e);
};

鼠标事件
#include <QMouseEvent>

void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseDoubleClickEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);

setMouseTracking(true);

void Widget::mousePressEvent(QMouseEvent *e)
{
    //this->ui->textEdit->append("mouse pressed");
    if(e->button()==Qt::LeftButton)
    {
        this->ui->textEdit->append("left button pressed");
        this->setCursor(Qt::PointingHandCursor);
        //改变光标图形
        //QCursor cur(QPixmap(":images/1.png"));
        //QApplication::setOverrideCursor(cur);
    }

    if(e->button()==Qt::RightButton)
    {
        this->ui->textEdit->append("right button pressed");
    }
}

void Widget::mouseMoveEvent(QMouseEvent *e)
{
    //QString str=tr("x=%1,y=%2").arg(e->pos().x()).arg(e->pos().y());
    if(e->buttons()&Qt::LeftButton)
    {
      QString str=tr("x=%1,y=%2").arg(e->globalPos().x()).arg(e->globalPos().y());
    this->ui->textEdit->append(str);
    this->ui->label->move(e->pos().x(),e->pos().y());
    }
}

void Widget::mouseDoubleClickEvent(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
    {
        this->ui->textEdit->append(tr("double lef key"));
    }

    if(e->button()==Qt::RightButton)
    {
        this->ui->textEdit->append(tr("double right key"));
    }
}

void Widget::mouseReleaseEvent(QMouseEvent *e)
{
    this->setCursor(Qt::ArrowCursor);
}

 

键盘事件
#include <QKeyEvent>

void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e);

void Widget::keyPressEvent(QKeyEvent *e)
{
    if(e->key()==Qt::Key_A)
    {
        this->ui->textEdit->setText("A");
    }
    if(e->key()==Qt::Key_0)
    {
        this->ui->textEdit->setText("0");
    }

    if(e->key()==Qt::Key_F3)
    {
        this->ui->textEdit->setText("F3");
    }
    if(e->key()==Qt::Key_Shift)
    {
         this->ui->textEdit->setText("shift");
    }
    if(e->key()==Qt::Key_Return)
    {
         this->ui->textEdit->setText("enter");
    }
    if(e->key()==Qt::Key_Escape)
    {
         this->ui->textEdit->setText("Esc");
    }
    if(e->key()==Qt::Key_Up)
    {
        this->ui->textEdit->setText("Up");
    }
    if(e->modifiers()==Qt::ShiftModifier && e->key()==Qt::Key_A)
    {
       this->ui->textEdit->setText("shif+A");
    }
}

void Widget::keyReleaseEvent(QKeyEvent *e)
{
}


关闭事件
#include <QCloseEvent>

 void closeEvent(QCloseEvent * e);

void Widget::closeEvent(QCloseEvent *e)
{
    QMessageBox::StandardButton btn=QMessageBox::question(this,"question",tr("是否关闭?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::No);
    if(btn==QMessageBox::Yes)
    {
        e->accept();
    }
    if(btn==QMessageBox::No)
    {
        e->ignore();
    }
}

 

 

 

右键菜单

#include <QContextMenuEvent>

void contextMenuEvent(QContextMenuEvent * e);

void Widget::contextMenuEvent(QContextMenuEvent *e)
{
    QAction *ac1=new QAction(tr("菜单1"),this);
    connect(ac1,SIGNAL(triggered()),this,SLOT(cdslot()));
    QMenu *menu=new QMenu;
    menu->addAction(ac1);
    menu->exec(e->globalPos());
}

 

//重写一个event方法实现所有事件功能

protected:
    bool event(QEvent *e);


bool Widget::event(QEvent *e)
{
    //判断事件类型
    if(e->type()==QEvent::MouseMove)
    {
        //将基类转换成派生类
        QMouseEvent *me=static_cast<QMouseEvent*>(e);
       et1->append(tr("x=%1;y=%2").arg(me->pos().x()).arg(me->pos().y()));
    return true;
    }
    if(e->type()==QEvent::MouseButtonDblClick)
    {
        QMouseEvent * me=dynamic_cast<QMouseEvent*>(e);
        if(me->button()==Qt::LeftButton)
        {
            et1->append(tr("left button press"));
        return  true;
        }
    }
    if(e->type()==QEvent::KeyPress)
    {
        QKeyEvent *ke=static_cast<QKeyEvent*>(e);
        if(ke->key()==Qt::Key_A)
        {
           et1->append(tr("A"));
        return true;
        }
    }

    if(e->type()==QEvent::Close)
    {
        QCloseEvent *ce=static_cast<QCloseEvent*>(e);
       // e->ignore();
        e->accept();
     return true;
    }
    //如果派生类没有完成事件,基类完成
    return QWidget::event(e);
}


事件过滤器

监控所有对象可能发生的事件

事件过滤器使用的步骤:
1.重写eventFilter 方法
2.在构造函数中注册每个部件到事件过滤器


protected:
    bool eventFilter(QObject * obj, QEvent * e);
 //obj:标记事件发生对象
      // e:标记事件


//注册部件到事件过滤器
this->ui->textEdit->installEventFilter(this);
this->ui->textEdit_2->installEventFilter(this);
this->installEventFilter(this);


bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    if(obj==this->ui->textEdit)
    {
        if(e->type()==QEvent::FocusIn)
        {
            this->ui->textEdit->setText("in");
            return true;
        }

        if(e->type()==QEvent::FocusOut)
        {
            this->ui->textEdit->setText("out");
            return true;
        }
    }

    if(obj==this->ui->textEdit_2)
    {
        if(e->type()==QEvent::FocusIn)
        {
            this->ui->textEdit_2->setText("in");
            return true;
        }

        if(e->type()==QEvent::FocusOut)
        {
            this->ui->textEdit_2->setText("out");
            return true;
        }
    }

    if(obj==this)
    {
        if(e->type()==QEvent::MouseButtonDblClick)
        {
            this->ui->textEdit->setText("double press");
            return true;
        }
    }
    return QWidget::eventFilter(obj,e);
}