Qt知识点汇总

说明

最近加入T公司,需要使用Qt进行PC下的界面应用开发,因此总结了一些Qt的常见用法在这里,以便学习(我一个linux后台开始玩Qt,也是造化弄人);

QT UI

QT开发过程中,QT通过一个后缀为ui的文件来描述应用程序的界面信息,该ui文件内容实质上是要给xml文件。

在开发过程中,可以通过相关的UI工具(例如qtDesinger)等工具生成该ui文件。

在编译过程中,该ui文件会被qt的ui处理工具uic转换为标准的c++文件, 生成的标准c++文件可以被引用以及被标准c++编译器编译。

非集成开发环境下,uic工具使用如下:

在集成开发环境中,大部分情况下ui文件会被转换为ui_XXX.h文件。

Qt 资源文件

在QT应用开发中,通过qrc文件描述应用使用到的资源文件(图片,音视频等)。Qrc文件的实质是一个xml文件,在文件中描述了资源名称与资源文件的关系,qt提供了一个工具rcc将qrc文件转换成标准的cpp文件,然后可以通过标准c++编译器使用该资源文件信息。

对于外挂资源,可以通过在rcc工具执行时添加-binary参数达到,添加后生成一个rcc文件,在代码中通过QResource::registerResource("/path/to/myresource.rcc");可以将该外挂资源集成到应用程序内部进行使用。

QT UI文件编译

Vs2019开发环境与QT集成后,ui界面文件x.ui对应的ui_XX.h文件由uic.exe自动生成,该生成文件路径可以通过以下方式设置:

右键ui文件选择属性,调整output变量取值。

QT+VS2019命令行编译

项目目录下执行以下命令

qmake -project QT+=widgets

qmake

nmake Debug Release

注意事项

打开的vs2019 cmd命令行,需要根据实际情况选择对应的架构x86或x64

QT MOC机制

QT的元对象系统是一个基于标准C++的扩展,能够使c++更好的适应GUI编程,支持开发人员在执行期获取对象的信息,同时这一机制也支持属性以及文本翻译(国际化,多语言)。

由于标准C++并没有提供动态元信息的支持,因此qt通过一个单独的工具moc来处理这个问题,moc工具会解析头文件中被Q_OBJECT宏声明的类,并生成一个单独的标准cpp文件来实现,因此对任何c++编译器而言,QT的moc机制都可以正常工作。

在具体的代码编写中,只有继承自QObject的类中,才可以通过宏Q_OBJECT进行修饰,从而转变成要给元对象。

对于一个元对象,它有如下一些特点

1:可以支持QT特有的signals和slots机制,在不同对象之间进行通信。

2:可以支持QObject::metaObject方法,用于返回类关联的元对象。

3:可以支持QMetaObject::className,用于在执行期获取对象的类名。

4:可以支持QObject::inherits方法,用于判断一个对象是否继承自QObject

5:可以支持QObject::setProperty和QObject::property方法,用于动态的设置和获取属性名称。

6:可以支持通过QMetaObject::newInstance用于构造一个新的实例。

在使用QT的MOC机制时,存在的一些限制

1:不能对模板类使用MOC机制(模板类无法继承自QObject)。

2:多重继承时QObject必须是第一个,且不支持QObject的虚继承。

3:函数指针不能作为信号或槽的参数。但通过typedef简化后的函数指针可以作为槽函数的参数。

4:信号和槽函数的参数必须是完全名称限定。

5:内嵌类不能有信号和槽。

6:信号和槽函数返回不能是引用。

QT中的信号和槽

信号(signal),就是特定情况下被发射的事件。

槽(slot)就是对信号的响应函数,就是一个函数。

Signal与slot之间的关联,是通过QObject::connect函数实现, 基本格式如下:

QObject::connect(sender,SIGNAL(signal()), receiver, SLOT(slot()))。

一个singal可以connect到多个slots;多个signal可以connect到同一个slot;一个signal可以connect到另外一个signal。

在使用signal与slots的类中,该类必须被宏Q_OBJECT修饰。

一般情况下,当一个signal被发射,与其关联的slot函数会立即被执行,只有所有slot函数被执行完成后,signal后的代码才会被执行。

自定义slot函数:

                任意的类成员函数,普通全局函数,静态函数都可以当做slot函数处理。Slot函数必须与signal信号一致(参数和返回值)。

自定义信号:

                信号必须通过关键字signal进行声明,signal没有返回值,但可以有参数,signal就是函数声明,无需实现。通过emit关键字进行signal的发射。

QT中几种connect到slot的方式

// 传统Qt4连接方式为 信号发送者,信号,信号接受者,处理函数

   QObject::connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(qT4_slot()));

//Qt5的新方法,在编译的时候就会有监测,如果我们手误操作失误,就会出现问题

    QObject::connect(ui->pushButton_2,&QPushButton::clicked,this,&Widget::qT5_slot);

  //Qt5 Lambda表达式

    //这里需要注意 Lambda表达式是C++ 11 的内容,所以,需要再Pro项目文件中加入CONFIG += C++ 11

   QObject::connect(ui->pushButton_3,&QPushButton::clicked,[=](){qDebug()<<"lambda表达式";});

QT事件机制

事件的产生:

                当用户按下鼠标/键盘等外部输入时产生事件,系统定时器,其他组件主动发起等也产生事件。

                Qt中所有的事件都继承自QEvent基类。

任何事件发生后,都会生成一个Event对象,该对象会被传递给特定组件的event处理函数,该event对象包含事件发生时所需要交互的所有信息。

            在应用执行过程中,用户可以产生自定义事件,有两种方式产生事件,一种是调用postEvent接口,另外是通过sendEvent接口产生,postEvent产生的是异步事件,事件会被放入Qt消息队列中,等待被依次处理,sendEvent产生的事件不会放入队列,而是直接派发和处理。

事件的处理:

            每个组件都定义了一组mousePressEvent相关的函数,用于处理对应的事件。对于自定义组件,可以通过重写这些方法对事件进行特殊处理。

                此外通过重新组件的event接口可以控制是否对某个事件进行处理。

事件过滤:

                有多个组件对象,例如A,B,通过A监视B的事件,可以在A中处理传递给B的事件。其基本过程如下:

                首先B调用installEventFilter接口注册监视对象A(如果有多个组件都需要被A监视,其他组件也需要调用该接口注册A)。

                在A的eventFilter接口中对事件进行处理,即如果一个事件被发送给B,在该事件被B处理之前,会优先调用A的eventFilter接口,在该接口中可以具体完成特定功能。

QT关键组件及使用方法

GraphicView

Graphic View是QT4之后面向对象的绘图机制,主要包括三个主要的类,QGraphicsScene(场景),QGraphicsView(视图),QGraphicsItem(图元),其中QGraphicsScene本身不可见,是一个存储QGraphicsItem的容器,要呈现QGraphicsScene内的内容,必须将QGraphicsScene与QGraphicsView关联起来进行交互;QGraphicsScene主要提供了操作QGraphicsItem的接口,事件传递以及无变换绘制等功能。

QGraphicsView提供了一个窗口,用于显示QGraphicsScene中的QGraphicsItem,一个QGraphicsScene场景可以关联多个QGraphicsView进行显示。

QGraphicsItem是需要呈现的基础类,QT提供了一些已经封装好的标准类,主要有下面这些:

QGraphicsSimpleTextItem:提供了一个简单的文本标签项

QGraphicsTextItem:提供了一个格式化的文本项

QGraphicsLineItem:提供了一个直线项

QGraphicsPixmapItem:提供了一个图像项

QGraphicsRectItem:提供了一个矩形项

QGraphicsEllipseItem:提供了一个椭圆项

QGraphicsPathItem:提供了一个路径项

QGraphicsPolygonItem:提供了一个多边形项

QgraphicsView坐标系

Graphics View坐标系基于笛卡尔坐标系,图元的位置和几何形状通过x坐标和y坐标表示,当使用没有变换的试图观察场景时,场景中的一个单位对应屏幕上的一个像素。在GraphicsView架构中,主要有3个有效坐标系统。

图元坐标:图元坐标位于自己的本地坐标上,图元的坐标通常以图元中心为原点,x轴向右,y轴向下,在自定义图元时,只需要注意图元的坐标既可。

子图元的坐标与父图元的坐标相关,如果子图元无变换,子图元坐标与父图元坐标相同,父图元变换时,子图元会隐式的被变换,但子图元的坐标不会被父图元的变换所影响。

场景坐标:场景坐标是所有图元的基础坐标,场景坐标描述了最顶层的图元位置,每个图元在场景中都有场景坐标和边界矩形,场景坐标的原点在场景中心,x轴向右,y轴向下。

视图坐标:视图坐标是窗口部件的坐标,视图坐标的单位是像素,左上角是远点,为了与图元交互,需要将图元坐标转换为场景坐标。

在Graphics View中,提供了对应的接口在几个坐标系之间进行转换。

QGraphicsView::mapToScene()视图到场景

QGraphicsView::mapFromScene()场景到视图

QGraphicsItem::mapFromScene()  场景到图元

QGraphicsItem::mapToScene()  图元到场景

QGraphicsItem::mapToParent()  子图元到父图元

QGraphicsItem::mapFromParent()父图元到子图元

QGraphicsItem::mapToItem()本图元到其他图元

QGraphicsItem::mapFromItem()其他图元到本图元

例如如果想在view坐标的原点开始绘制一条线段,可以通过如下方式处理

   1:调用view接口QGraphicsView::mapToScene()将view原点变换到scence坐标系中。

   2:调用item接口QGraphicsItem::mapFromScene()  将坐标从scence变换为item坐标系,然后调用item的setLine接口进行线段绘制。

样例代码如下:

QgraphicsView上绘制可编辑文字

QgraphicsView展示图片

QGraphicsView上展示图片可以通过QPixmap类以及接口addPixmap实现。样例代码如下:

常见问题

1:error C2001: 常量中有换行符

QT编码中,字符串中存在中文等字符时,有时候会报“error C2001: 常量中有换行符”错误,对于该错误,可以在字符串后面添加一个空格规避。

2:QgraphicsView坐标对齐

默认情况下scence的原点会出现在view的中间,此时可以通过调用setAlignment进行对齐。

例如以左上角方式对齐:

view->setAlignment(Qt::AlignLeft | Qt::AlignTop); 在这种方式下绘图比较方便。

3:QgraphicsView曲线平滑

此外进行线条绘制时,默认并没有开启线条平滑,此时可以通过调用view->setRenderHint(QPainter::Antialiasing);设置平滑线条。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • QT常用函数概述 setWindowTitle("string"): 设置标题 setText("string")...
    梦幽辰阅读 383评论 0 0
  • 1 实验目的 目前计算机视觉技术已经比较成熟,相关的开源项目与算法很多,可以将这些开源算法进行整合,进而做成一个小...
    YOUNG_FAN阅读 6,675评论 0 50
  • 《Qt 学习之路 2》原文地址 Qt跨平台策略 GUI 模拟:任何平台都提供了图形绘制函数,例如画点、画线、画面等...
    CharlesZhangCh阅读 1,986评论 0 5
  • 韩元旭、余橙、沈开洋 Qt介绍 Qt是一个跨平台的C++图形用户界面应用程序框架。它早在1991年奇趣科技公司两位...
    开洋_shen阅读 16,157评论 4 24
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,548评论 0 11