QT学习之路全.docx

上传人:b****5 文档编号:12305291 上传时间:2023-04-18 格式:DOCX 页数:214 大小:1.79MB
下载 相关 举报
QT学习之路全.docx_第1页
第1页 / 共214页
QT学习之路全.docx_第2页
第2页 / 共214页
QT学习之路全.docx_第3页
第3页 / 共214页
QT学习之路全.docx_第4页
第4页 / 共214页
QT学习之路全.docx_第5页
第5页 / 共214页
点击查看更多>>
下载资源
资源描述

QT学习之路全.docx

《QT学习之路全.docx》由会员分享,可在线阅读,更多相关《QT学习之路全.docx(214页珍藏版)》请在冰豆网上搜索。

QT学习之路全.docx

QT学习之路全

QT学习之路

二维画图中视口坐标与窗口坐标

视口坐标系是对物理坐标系而言,也就是我们平常画图使用的坐标系(通常相对屏幕或者父窗口部件);窗口坐标系是我们自己定义的逻辑坐标系,根据画图的方面而自定义的。

在默认情况下,视口坐标系与窗口坐标系是一致的。

在Qt中我们画图时坐标都是相对于窗口坐标系,而与视口坐标系无关。

    比如:

比如我们要一个矩形(0,0,320,200)(视口坐标)内画图,而我们可以定义这个矩形的窗口坐标为(-50,-50,100,100);窗口坐标系统相对与视口坐标系做了平移与缩放。

在视口坐标系矩形的左上角坐标为(0,0),宽度为320,高度为200的长方形;而在窗口坐标系中这个矩形的左上角坐标为(-50,-50),宽度为100,高度为100的正方形。

    坐标的转换公式:

(x0-m)*Rx=(X-0)      (Y0-n)*Ry=Y-0  

    Rx为X轴的缩放因子,Ry为Y轴的缩放因子.

Qt学习之路

(1)

Qt是一个著名的C++库——或许并不能说这只是一个GUI库,因为Qt十分庞大,并不仅仅是GUI。

使用Qt,在一定程序上你获得的是一个“一站式”的服务:

不再需要研究STL,不再需要C++的,因为Qt有它自己的QString等等。

或许这样说很偏激,但Qt确实是一个“伟大的C++库”。

我们所使用的Qt,确切地说也就是它的GUI编程部分。

C++的GUI编程同Java不同:

GUI并不是C++标准的一部分。

所以,如果使用Java,那么你最好的选择就是AWT/Swing,或者也可以使SWT/JFace,但是,C++的GUI编程给了你更多的选择:

wxWidget,gtk++以及Qt。

这几个库我都有接触,但是接触都不是很多,只能靠一些资料和自己的一点粗浅的认识说一下它们之间的区别(PS:

更详尽的比较在前面的文章中有)。

首先说wxWidget,这是一个标准的C++库,和Qt一样庞大。

它的语法看上去和MFC类似,有大量的宏。

据说,一个MFC程序员可以很容易的转换到wxWidget上面来。

wxWidget有一个很大的优点,就是它的界面都是原生风格的。

这是其他的库所不能做到的。

wxWidget的运行效率很高,据说在Windows平台上比起微软自家的MFC也不相上下。

gtk++其实是一个C库,不过由于C++和C之间的关系,这点并没有很大的关系。

但是,gtk++是一个使用C语言很优雅的实现了面向对象程序设计的范例。

不过,这也同样带来了一个问题——它的里面带有大量的类型转换的宏来模拟多态,并且它的函数名“又臭又长(不过这点我倒是觉得无所谓,因为它的函数名虽然很长,但是同样很清晰)”,使用下划线分割单词,看上去和Linux如出一辙。

由于它是C语言实现,因此它的运行效率当然不在话下。

gtk++并不是模拟的原生界面,而有它自己的风格,所以有时候就会和操作系统的界面显得格格不入。

再来看Qt,和wxWidget一样,它也是一个标准的C++库。

但是它的语法很类似于Java的Swing,十分清晰,而且SIGNAL/SLOT机制使得程序看起来很明白——这也是我首先选择Qt的一个很重要的方面,因为我是学Java出身的。

不过,所谓“成也萧何,败也萧何”,这种机制虽然很清楚,但是它所带来的后果是你需要使用Qt的qmake对程序进行预处理,才能够再使用make或者nmake进行编译。

并且它的界面也不是原生风格的,尽管Qt使用style机制十分巧妙的模拟了本地界面。

另外值得一提的是,Qt不仅仅运行在桌面环境中,Qt已经被Nokia收购,它现在已经会成为Symbian系列的主要界面技术——Qt是能够运行于嵌入式平台的。

以往人们对Qt的授权多有诟病。

因为Qt的商业版本价格不菲,开源版本使用的是GPL协议。

但是现在Qt的开源协议已经变成LGPL。

这意味着,你可以将Qt作为一个库连接到一个闭源软件里面。

可以说,现在的Qt协议的争议已经不存在了——因为wxWidgets或者gtk+同样使用的是类似的协议发布的。

在本系列文章中,我们将使用Qt4进行C++GUI的开发。

我是参照着《C++GUIProgrammingwithQt4》一书进行学习的。

其实,我也只是初学Qt4,在这里将这个学习笔记记下来,希望能够方便更多的朋友学习Qt4。

我是一个Java程序员,感觉Qt4的一些命名规范以及约束同Java有异曲同工之妙,因而从Java迁移到Qt4似乎困难不大。

不过,这也主要是因为Qt4良好的设计等等。

闲话少说,还是尽快开始下面的学习吧!

Qt学习之路(2/3):

Hello,world!

任何编程技术的学习第一课基本上都会是Hello,world!

,我也不想故意打破这个惯例——照理说,应该首先回顾一下Qt的历史,不过即使不说这些也并无大碍。

  或许有人总想知道,Qt这个单词是什么意思。

其实,这并不是一个缩写词,仅仅是因为它的发明者,TrollTech公司的CEO,HaarardNord和Trolltech公司的总裁EirikChambe-Eng在联合发明Qt的时候并没有一个很好的名字。

在这里,字母Q是Qt库中所有类的前缀——这仅仅是因为在Haarard的emacs的字体中,这个字母看起来特别的漂亮;而字母t则代表“toolkit”,这是在Xt(Xtoolkit)中得到的灵感。

  顺便说句,Qt原始的公司就是上面提到的Trolltech,貌似有一个中文名字是奇趣科技——不过现在已经被Nokia收购了。

因此,一些比较旧的文章里面会提到Trolltech这个名字。

  好了,闲话少说,先看看Qt的开发吧!

事先说明一下,我是一个比较懒的人,不喜欢配置很多的东西,而Qt已经提供了一个轻量级的IDE,并且它的网站上也有forEclipse和VS的开发插件,不过在这里我并不想用这些大块头。

Qt有两套协议——商业版本和开源的LGPL版本。

不同的是前者要收费,而后者免费,当然,后者还要遵循LGPL协议的规定,这是题外话。

安装完成后会有个QtCreator的东西,这就是官方提供的一个轻量级IDE,不过它的功能还是蛮强大的。

运行这个就会发现,其实Qt不仅仅是LinuxKDE桌面的底层实现库。

而且是这个IDE的实现的这个IDE就是用Qt完成的。

  QtCreator左面从上到下依次是Welcome(欢迎页面,就是一开始出现的那个);Edit(我们的代码编辑窗口);Debug(调试窗口);Projects(工程窗口);Help(帮助,这个帮助完全整合的Qt的官方文档,相当有用);Output(输出窗口)。

  下面我们来试试我们的Hello,world!

吧!

  在Edit窗口空白处点右键,有Newproject...这里我们选第三项,QtGuiApplication。

  然后点击OK,来到下一步,输入工程名字和保存的位置。

  点击Next,来到选择库的界面。

这里我们系统默认为我们选择了Qtcore和GUI,还记得我们建的是GuiApplication吗?

嗯,就是这里啦,它会自动为我们加上gui这个库。

现在应该就能看出,Qt是多么庞大的一个库,它不仅仅有Gui,而且有Network,OpenGL,XML之类。

不过,现在在这里我们不作修改,直接Next。

编缉推荐阅读以下文章

                      

∙Qt学习之路(10):

Meta-Object系统

∙Qt学习之路(9):

深入了解信号槽

∙Qt学习之路(8):

创建一个对话框(下)

∙Qt学习之路(7):

创建一个对话框(上)

∙Qt学习之路(6):

API文档的使用

∙Qt学习之路(5):

组件布局

∙Qt学习之路(4):

初探信号槽

∙Qt学习之路(3):

Hello,world!

(续)

∙Qt学习之路

(1):

前言

                                                        

  下一个界面需要我们定义文件名,我们不修改默认的名字,只是为了清楚起见,把generateform的那个勾去掉即可。

  Next之后终于到了Finish了——漫长的一系列啊!

检查无误后Finish就好啦!

  之后可以看到,IDE(即Qtcreator)自动生成了四个文件,一个.pro文件,两个.cpp和一个.h。

这里说明一下,.pro就是工程文件(project),它是qmake自动生成的用于生产makefile的配置文件。

这里我们先不去管它。

main.cpp里面就是一个main函数,其他两个文件就是先前我们曾经指定的文件名的文件。

  现在,我们把main.cpp中的代码修改一下:

#include

#include

 

intmain(intargc,char*argv[])

{

       QApplicationapp(argc,argv);

       QLabel*label=newQLabel("Hello,world!

");

       label->show();

       returnapp.exec();

}

  修改完成后保存。

点击左下角的绿色三角键,Run。

一个小小的窗口出现了——

  好了!

我们的第一个Qt程序已经完成了。

  PS:

截了很多图,说得详细些,以后可就没这么详细的步骤啦,嘿嘿…相信很多朋友应该一下子就能看明白这个IDE应该怎么使用了的,无需我多费口舌。

呵呵。

下面来逐行解释一下前面的那个Hello,world!

程序,尽管很简单,但却可以对Qt程序的结构有一个清楚的认识。

现在再把代码贴过来:

#include

#include

intmain(intargc,char*argv[])

{

       QApplicationapp(argc,argv);

       QLabel*label=newQLabel("Hello,world!

");

       label->show();

       returnapp.exec();

}

  第1行和第2行就是需要引入的头文件。

和普通的C++程序没有什么两样,如果要使用某个组件,就必须要引入相应的头文件,这类似于Java的import机制。

值得说明的是,Qt中头文件和类名是一致的。

也就是说,如果你要使用某个类的话,它的类名就是它的头文件名。

第3行是空行

第4行是main函数函数头。

这与普通的C++程序没有什么两样,学过C++的都明白。

因此你可以看到,实际上,Qt完全通过普通的main函数进入,这不同于wxWidgets,因为wxWidgets的Hello,world需要你继承它的一个wxApp类,并覆盖它的wxApp:

:

OnInit方法,系统会自动将OnInit编译成入口函数。

不过在Qt中,就不需要这些了。

  第5行,噢噢,大括号…

  第6行,创建一个QApplication对象。

这个对象用于管理应用程序级别的资源。

QApplication的构造函数要求两个参数,分别来自main的那两个参数,因此,Qt在一定程度上是支持命令行参数的。

  第7行,创建一个QLabel对象,并且能够显示Hello,world!

字符串。

和其他库的Label控件一样,这是用来显示文本的。

在Qt中,这被称为一个widget(翻译出来是小东西,不过这个翻译并不好…),它等同于Windows技术里面的控件(controls)和容器(containers)。

也就是说,widget可以放置其他的widget,就像Swing的组件。

大多数Qt程序使用QMainWindow或者QDialog作为顶级组件,但Qt并不强制要求这点。

在这个例子中,顶级组件就是一个QLabel。

  第8行,使这个label可见。

组件创建出来之后通常是不可见的,要求我们手动的使它们可见。

这样,在创建出组建之后我们就可以对它们进行各种定制,以避免出现之后在屏幕上面会有闪烁。

  第9行,将应用程序的控制权移交给Qt。

这时,程序的事件循环就开始了,也就是说,这时可以相应你发出的各种事件了。

这类似于gtk+最后的一行gtk_main()。

  第10行,大括号……程序结束了。

  注意!

,我们并没有使用delete去删除创建的QLabel,因为在程序结束后操作系统会回收这个空间——这只是因为这个QLabel占用的内存比较小,但有时候这么做会引起麻烦的,特别是在大程序中,因此必须小心。

  好了,程序解释完了。

按照正常的流程,下面应该编译。

前面也提过,Qt的编译不能使用普通的make,而必须先使用qmake进行预编译。

所以,第一步应该是在工程目录下使用

  qmake-project

  命令创建.pro文件(比如说是叫helloworld.pro)。

然后再在.pro文件目录下使用

qmakehelloworld.pro (make)

或者  qmake-tpvchelloworld.pro (nmake)

生成makefile,然后才能调用make或者是nmake进行编译。

不过因为我们使用的是IDE,所以这些步骤就不需要我们手动完成了。

  值得说明一点的是,这个qmake能够生成标准的makefile文件,因此完全可以利用qmake自动生成makefile——这是题外话。

  好了,下面修改一下源代码,把QLabel的创建一句改成

  QLabel*label=newQLabel("

Hello,world!

");

  运行一下:

  同Swing的JLabel一样,Qt也是支持HTML解析的。

  好了,这个Hello,world就说到这里!

明确一下Qt的程序结构,在一个Qt源代码中,以下两条语句是必不可少的!

!

QApplicationapp(argc,argv);

//...

returnapp.exec();

Qt学习之路(4):

初探信号槽

看过了简单的Hello,world!

之后,下面来看看Qt最引以为豪的信号槽机制!

  所谓信号槽,简单来说,就像是插销一样:

一个插头和一个插座。

怎么说呢?

当某种事件发生之后,比如,点击了一下鼠标,或者按了某个按键,这时,这个组件就会发出一个信号。

就像是广播一样,如果有了事件,它就漫天发声。

这时,如果有一个槽,正好对应上这个信号,那么,这个槽的函数就会执行,也就是回调。

就像广播发出了,如果你感兴趣,那么你就会对这个广播有反应。

干巴巴的解释很无力,还是看代码:

#include

#include

intmain(intargc,char*argv[])

{

       QApplicationa(argc,argv);

       QPushButton*button=newQPushButton("Quit");

QObject:

:

connect(button,SIGNAL(clicked()),&a,SLOT(quit()));

       button->show();

    returna.exec();

}

  这是在QtCreator上面新建的文件,因为前面已经详细的说明怎么新建工程,所以这里就不再赘述了。

这个程序很简单,只有一个按钮,点击之后程序退出。

(顺便说一句,Qt里面的button被叫做QPushButton,真搞不明白为什么一个简单的button非得加上push呢?

呵呵)

主要是看这一句:

QObject:

:

connect(button,SIGNAL(clicked()),&a,SLOT(quit()));

  QObject是所有类的根。

Qt使用这个QObject实现了一个单根继承的C++。

它里面有一个connect静态函数,用于连接信号槽。

  当一个按钮被点击时,它会发出一个clicked信号,意思是,向周围的组件们声明:

我被点击啦!

当然,其它很多组件都懒得理他。

如果对它感兴趣,就告诉QObject说,你帮我盯着点,只要button发出clicked信号,你就告诉我——想了想之后,说,算了,你也别告诉我了,直接去执行我的某某某函数吧!

就这样,一个信号槽就形成了。

具体来说呢,这个例子就是QApplication的实例a说,如果button发出了clicked信号,你就去执行我的quit函数。

所以,当我们点击button的时候,a的quit函数被调用,程序退出了。

所以,在这里,clicked()就是一个信号,而quit()就是槽,形象地说就是把这个信号插进这个槽里面去。

  Qt使用信号槽机制完成了事件监听操作。

这类似与Swing里面的listener机制,只是要比这个listener简单得多。

以后我们会看到,这种信号槽的定义也异常的简单。

值得注意的是,这个信号槽机制仅仅是使用的QObject的connect函数,其他并没有什么耦合——也就是说,完全可以利用这种机制实现你自己的信号监听!

不过,这就需要使用qmake预处理一下了!

  细心的你或许发现,在QtCreator里面,SIGNAL和SLOT竟然变颜色了!

没错,Qt确实把它们当成了关键字!

实际上,Qt正是利用它们扩展了C++语言,因此才需要使用qmake进行预处理,比便使普通的C++编译器能够顺利编译。

另外,这里的signal和Unix系统里面的signal没有任何的关系!

哦哦,有一点关系,那就是名字是一样的!

  信号槽机制是Qt关键部分之一,以后我们还会再仔细的探讨这个问题的。

Qt学习之路(5):

组件布局(布局:

Layout)

顾名思义,绝对定位就是使用最原始的定位方法,给出这个组件的坐标和长宽值。

这样,Qt就知道该把组件放在哪里,以及怎么设置组件的大小了。

但是这样做的一个问题是,如果用户改变了窗口大小,比如点击了最大化或者拖动窗口边缘,这时,你就要自己编写相应的函数来响应这些变化,以避免那些组件还只是静静地呆在一个角落。

或者,更简单的方法是直接禁止用户改变大小。

不过,Qt提供了另外的一种机制,就是布局,来解决这个问题。

你只要把组件放入某一种布局之中,当需要调整大小或者位置的时候,Qt就知道该怎样进行调整。

这类似于Swing的布局管理器,不过Qt的布局没有那么多,只有有限的几个。

  来看一下下面的例子:

#include

#include

#include

#include

#include

intmain(intargc,char*argv[])

{

 QApplicationapp(argc,argv);

 QWidget*window=newQWidget;

 window->setWindowTitle("Enteryourage");

 QSpinBox*spinBox=newQSpinBox;

 QSlider*slider=newQSlider(Qt:

:

Horizontal);

 spinBox->setRange(0,130);

 slider->setRange(0,130);

QObject:

:

connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));

QObject:

:

connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));

spinBox->setValue(35);

       QHBoxLayout*layout=newQHBoxLayout;

       layout->addWidget(spinBox);

       layout->addWidget(slider);

       window->setLayout(layout);

       window->show();

       returnapp.exec();

}

编缉推荐阅读以下文章

                

∙Qt学习之路(10):

Meta-Object系统

∙Qt学习之路(9):

深入了解信号槽

∙Qt学习之路(8):

创建一个对话框(下)

∙Qt学习之路(7):

创建一个对话框(上)

∙Qt学习之路(6):

API文档的使用

∙Qt学习之路(4):

初探信号槽

∙Qt学习之路(3):

Hello,world!

(续)

∙Qt学习之路

(2):

Hello,world!

∙Qt学习之路

(1):

前言

这里使用了两个新的组件:

QSpinBox和QSlider,以及一个新的顶级窗口QWidget。

QSpinBox是一个有上下箭头的微调器,QSlider是一个滑动杆,只要运行一下就会明白到底是什么东西了。

  代码并不是那么难懂,还是来简单的看一下。

首先创建了一个QWidget的实例,调用setWindowTitle函数来设置窗口标题。

然后创建了一个QSpinBox和QSlider,分别设置了它们值的范围,使用的是setRange函数。

然后进行信号槽的链接。

这点后面再详细说明。

然后是一个QHBoxLayout,就是一个水平布局,按照从左到右的顺序进行添加,使用addWidget添加好组件后,调用QWidget的setLayout把QWidget的layout设置为我们定义的这个Layout,这样,程序就完成了!

  编译运行一下,可以看到效果:

  如果最大化的话:

  虽然我并没有添加任何代码,但是那个layout就已经明白该怎样进行布局。

或许你发现,那两个信号槽的链接操作会不会产生无限递归?

因为steValue就会引发valueChanged信号!

答案是不会。

这两句语句实现了,当spinBox发出valueChanged信号的时候,会回调slider的setValue,以更新slider的值;而slider发出valueChanged信号的时候,又会回调slider的setValue。

但是,如果新的value和旧的value是一样的话,是不会发出这个信号的,因此避免了无限递归。

   编缉推荐阅读以下文章

                

∙Qt学习之路(10):

Meta-Object系统

∙Qt学习之路(9):

深入了解信号槽

∙Qt学习之路(8):

创建一个对话框(下)

∙Qt学习之路(7):

创建一个对话框(上)

∙Qt学习之路(6):

API文档的使用

∙Qt学习之路(4):

初探信号槽

∙Qt学习之路(3):

Hello,worl

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1