Qt入门培训学习.pptx
Qt简介Qt的使用Qt深入理解Qt的应用第1页/共110页Qt简介什么是Qt?第2页/共110页什么是Qt?原来用作用户界面开发,现可用作所有的开发例如:Databases,XML,WebKit,multimedia,networking,OpenGL,scripting,non-GUI.”Qt是一个用C+编写的跨平台开发框架.”第3页/共110页什么是Qt?Qt由模块构建QtCorePhononQtXmlPatternsQtXmlQtWebKitQtSvgQtSqlQtScriptQtOpenVGQtOpenGLQtNetworkQtMultimediaQtGui第4页/共110页什么是QT?Qt用宏(macros)和内省(introspection)扩展了C+所有的代码仍然是简明C+foreach(intvalue,intList)QObject*o=newQPustButton;o-metaObject()-className();/返回”QPushButton”connect(button,SIGNAL(clicked(),window,SLOT(close();第5页/共110页Qt的目的一次编写,到处编译根据不同平台的本地观感生成相应的本地应用简单地使用API,高开发效率,开放性,使用有趣第6页/共110页Qt的历史19901991199419992001Haavard和Eirik灵感闪现开始设计,并提出信号和槽的概念1993开发出Qt的第一个图形核心命名为Qt,并建立“奇趣科技”1995签订第一个合同,开始快速发展。1997Qt1.2发布,并且用于开发KDE。Qt2.0发布Qt3.0发布。2005Qt4.0发布2008Nokia收购奇趣科技第7页/共110页Qt的跨平台桌面平台WindowsMacOSXLinux/UnixX11第8页/共110页Qt的跨平台嵌入式平台WindowsCESymbianMaemo嵌入式Linux第9页/共110页Qt的授权LGPL免费你的应用程序可以是开源的或者是不开源的对Qt的修改,必须反馈到社区GPL免费你的应用程序必须是开源的对Qt的修改,必须反馈到社区商业的收费你的应用程序可以是不开源的对Qt的修改,可以不开源第10页/共110页Qt简介Qt的使用Qt深入理解Qt的应用第11页/共110页Qt的代码结构-Hello World第12页/共110页Qt的代码结构-Hello World#include#includeintmain(intargc,char*argv)QApplicationapp(argc,argv);QLabell(HelloWorld!);l.show();returnapp.exec();第13页/共110页Qt的代码结构-Hello World#include#include intmain(intargc,char*argv)QApplicationapp(argc,argv);QLabell(HelloWorld!);l.show();returnapp.exec();第14页/共110页Qt的代码结构-Hello World#include#includeintmain(intargc,char*argv)QApplication app(argc,argv);QLabell(HelloWorld!);l.show();returnapp.exec();第15页/共110页Qt的代码结构-Hello World#include#includeintmain(intargc,char*argv)QApplicationapp(argc,argv);QLabel l(Hello World!);l.show();returnapp.exec();第16页/共110页Qt的代码结构-Hello World#include#includeintmain(intargc,char*argv)QApplicationapp(argc,argv);QLabell(HelloWorld!);l.show();return app.exec();第17页/共110页Qt开发工具集1.QtCreator2.QtDesigner3.QtLinguist4.QtAssisant5.QtDemos第18页/共110页信号(Signal)与槽(Slot)初探QT提供的一种在对象间进行通讯的技术。动态地或松散地将事件和状态变化联系起来。信号和槽机制是使Qt运作的元素。第19页/共110页信号(Signal)与槽(Slot)初探类似于windows中的消息和消息响应都是通过C+类成员函数实现的信号和槽是通过连接实现相互关联的包含信号或槽的类必须从QObject继承第20页/共110页信号(Signal)与槽(Slot)初探emitclicked();第21页/共110页信号(Signal)与槽(Slot)初探privateslots:voidon_addButton_clicked();voidon_deleteButton_clicked();connect(clearButton,SIGNAL(clicked(),listWidget,SLOT(clear();connect(addButton,SIGNAL(clicked(),this,SLOT(.);2xclear();第22页/共110页信号(Signal)与槽(Slot)初探.emitclicked();.emitclicked();.emitclicked();.QStringnewText=QInputDialog:getText(this,Entertext,Text:);if(!newText.isEmpty()ui-listWidget-addItem(newText);foreach(QListWidgetItem*item,ui-listWidget-selectedItems()deleteitem;clear();第23页/共110页信号(Signal)与槽(Slot)初探class Employee:public QObjectQ_OBJECTpublic:Employee();int salary()const;public slots:void setSalary(int newSalary);signals:void salaryChanged(int newSalary);private:int mySalary;emit salaryChanged(50);信号和槽的声明:第24页/共110页信号(Signal)与槽(Slot)初探第25页/共110页信号(Signal)与槽(Slot)初探信号与槽机制只能用在继承于QObject的类。槽可以返回值,但通过联接返回时不能有返回值,槽以一个普通的函数实现,可以作为普通函数调用。信号总是返回空,信号总是不必实现一个信号可以连接到多个槽,但槽的调用顺序不确定。信号和槽需要具有相同的参数列表;如果信号的参数比槽多,那么多余的参数会被忽略;如果参数列表不匹配,Qt会产生运行时错误信息第26页/共110页信号和槽vs回调回调(callback)是一个函数指针,当一个事件发生时被调用,任何函数都可以被安排作为回调。没有类型安全总是以直接调用方式工作信号和槽的方式更加动态一个更通用的机制更容易互连两个已存在的类相关类之间涉及更少的知识共享第27页/共110页用户界面设计用户界面由特定的部件(widget)构建第28页/共110页用户界面设计三种方式1.绝对定位(absolutepositioning)最粗劣的方式对部件的大小、位置进行硬编码2.手工布局(manuallayout)绝对位置,但通过resizeEvent()方法改变大小3.布局管理器(layoutmanagers)部件放置在布局管理器中,使界面更具弹性。第29页/共110页布局管理器的优点?让部件适应内容让部件适应翻译变化让部件适应用户设置第30页/共110页布局管理几种可用的布局布局管理器和部件“协商”各个部件大小与位置弹簧可以用来填充空白处QGridLayoutQVBoxLayoutQHBoxLayout第31页/共110页布局管理器示例对话框由多层的布局管理器和部件组成两种方式:代码实现,使用设计器注意:布局管理器并不是其管理的部件的父对象第32页/共110页布局管理器代码实现QVBoxLayout*outerLayout=newQVBoxLayout(this);QHBoxLayout*topLayout=newQHBoxLayout();topLayout-addWidget(newQLabel(Printer:);topLayout-addWidget(c=newQComboBox();outerLayout-addLayout(topLayout);QHBoxLayout*groupLayout=newQHBoxLayout();.outerLayout-addLayout(groupLayout);outerLayout-addSpacerItem(newQSpacerItem(.);QHBoxLayout*buttonLayout=newQHBoxLayout();buttonLayout-addSpacerItem(newQSpacerItem(.);buttonLayout-addWidget(newQPushButton(Print);buttonLayout-addWidget(newQPushButton(Cancel);outerLayout-addLayout(buttonLayout);第33页/共110页布局管理器代码实现QVBoxLayout*outerLayout=newQVBoxLayout(this);QHBoxLayout*topLayout=newQHBoxLayout();topLayout-addWidget(newQLabel(Printer:);topLayout-addWidget(c=newQComboBox();outerLayout-addLayout(topLayout);QHBoxLayout*groupLayout=newQHBoxLayout();.outerLayout-addLayout(groupLayout);outerLayout-addSpacerItem(newQSpacerItem(.);QHBoxLayout*buttonLayout=newQHBoxLayout();buttonLayout-addSpacerItem(newQSpacerItem(.);buttonLayout-addWidget(newQPushButton(Print);buttonLayout-addWidget(newQPushButton(Cancel);outerLayout-addLayout(buttonLayout);第34页/共110页布局管理器代码实现QVBoxLayout*outerLayout=newQVBoxLayout(this);QHBoxLayout*topLayout=newQHBoxLayout();topLayout-addWidget(newQLabel(Printer:);topLayout-addWidget(c=newQComboBox();outerLayout-addLayout(topLayout);QHBoxLayout*groupLayout=newQHBoxLayout();.outerLayout-addLayout(groupLayout);outerLayout-addSpacerItem(newQSpacerItem(.);QHBoxLayout*buttonLayout=newQHBoxLayout();buttonLayout-addSpacerItem(newQSpacerItem(.);buttonLayout-addWidget(newQPushButton(Print);buttonLayout-addWidget(newQPushButton(Cancel);outerLayout-addLayout(buttonLayout);第35页/共110页布局管理器代码实现QVBoxLayout*outerLayout=newQVBoxLayout(this);QHBoxLayout*topLayout=newQHBoxLayout();topLayout-addWidget(newQLabel(Printer:);topLayout-addWidget(c=newQComboBox();outerLayout-addLayout(topLayout);QHBoxLayout*groupLayout=newQHBoxLayout();.outerLayout-addLayout(groupLayout);outerLayout-addSpacerItem(newQSpacerItem(.);QHBoxLayout*buttonLayout=newQHBoxLayout();buttonLayout-addSpacerItem(newQSpacerItem(.);buttonLayout-addWidget(newQPushButton(Print);buttonLayout-addWidget(newQPushButton(Cancel);outerLayout-addLayout(buttonLayout);第36页/共110页布局管理器代码实现QVBoxLayout*outerLayout=newQVBoxLayout(this);QHBoxLayout*topLayout=newQHBoxLayout();topLayout-addWidget(newQLabel(Printer:);topLayout-addWidget(c=newQComboBox();outerLayout-addLayout(topLayout);QHBoxLayout*groupLayout=newQHBoxLayout();.outerLayout-addLayout(groupLayout);outerLayout-addSpacerItem(newQSpacerItem(.);QHBoxLayout*buttonLayout=newQHBoxLayout();buttonLayout-addSpacerItem(newQSpacerItem(.);buttonLayout-addWidget(newQPushButton(Print);buttonLayout-addWidget(newQPushButton(Cancel);outerLayout-addLayout(buttonLayout);第37页/共110页布局管理器代码实现QHBoxLayout*groupLayout=newQHBoxLayout();QGroupBox*orientationGroup=newQGroupBox();QVBoxLayout*orientationLayout=newQVBoxLayout(orientationGroup);orientationLayout-addWidget(newQRadioButton(Landscape);orientationLayout-addWidget(newQRadioButton(Portrait);groupLayout-addWidget(orientationGroup);QGroupBox*colorGroup=newQGroupBox();QVBoxLayout*colorLayout=newQVBoxLayout(colorGroup);colorLayout-addWidget(newQRadioButton(BlackandWhite);colorLayout-addWidget(newQRadioButton(Color);groupLayout-addWidget(colorGroup);Horizontalbox,包含groupboxes,verticalboxes,radiobuttons第38页/共110页布局管理器设计器可以使用设计器来建立同样的结构第39页/共110页通用部件Qt包含针对所有情形的大量通用部件;第三方控件,如QWT自定义控件第40页/共110页尺寸(size)的策略布局管理器是在空间和其他布局管理器之间进行协调布局管理器提供布局结构水平布局和垂直布局网格布局部件则提供各个方向上的尺寸策略最大和最小尺寸第41页/共110页尺寸的策略例子未完成!printerList-setSizePolicy(QSizePolicy:Expanding,QSizePolicy:Fixed)第42页/共110页尺寸的策略每一个widget有一个大小的示意,它给出了各个方向上尺寸的策略Fixed规定了widget的尺寸Minimum规定了可能的最小值Maximum规定可能的最大值Preferred给出最好的值但不是必须的Expanding同preferred,但希望增长MinimumExpanding同minimum,但希望增长Ignored忽略规定尺寸,widget得到尽量大的空间第43页/共110页如果?2个preferred相邻1个preferred,1个expanding2个expanding相邻空间不足以放置widget(fixed)第44页/共110页关于尺寸的更多信息可用最大和最小属性更好地控制widget的大小maximumSize最大可能尺寸minimumSize最小可能尺寸ui-pushButton-setMinimumSize(100,150);ui-pushButton-setMaximumHeight(250);第45页/共110页伸缩因子控制缩放时,各控件的缩放比例。第46页/共110页设计器介绍以前设计器(Designer)是一个独立的工具,但现在是QtCreator的一个组成部分可视化窗体编辑器拖放部件安排布局进行信号连接第47页/共110页设计器介绍sources*.cppexecutablesobjectfiles*.oheaders*.hgeneratedmoc_*.cppuserinterfaces*.uiincludescompileslinkscompilesmocs第48页/共110页设计器介绍sources*.cppexecutablesobjectfiles*.oheaders*.hgeneratedmoc_*.cppgeneratedui_*.huserinterfaces*.uiincludescompileslinkscompilesmocsuic第49页/共110页使用代码#ifndefWIDGET_H#defineWIDGET_H#includenamespaceUiclassWidget;classWidget:publicQWidgetQ_OBJECTpublic:Widget(QWidget*parent=0);Widget();private:Ui:Widget*ui;#endif/WIDGET_HUi:Widget类的前置声明一个Ui:Widget类指针ui,指向所有部件基本上一个标准的QWidget派生类第50页/共110页使用代码#includewidget.h#includeui_widget.hWidget:Widget(QWidget*parent):QWidget(parent),ui(newUi:Widget)ui-setupUi(this);Widget:Widget()deleteui;实例化类Ui:Widget为ui删除ui对象调用函数setupUi,生成所有父窗体(this)的子窗体部件第51页/共110页使用设计器基本工作流程粗略地放置部件在窗体上从里到外进行布局,添加必要的弹簧进行信号连接在代码中使用在整个过程中不断修改编辑属性实践创造完美!第52页/共110页使用设计器拖放部件拖放部件粗略地放置部件在窗体上第53页/共110页使用设计器从里到外进行布局,添加必要的弹簧121.选中每一个groupbox,2.应用垂直布局管理第54页/共110页使用设计器从里到外进行布局,添加必要的弹簧11.选中label(click),2.选中combobox(Ctrl+click)2第55页/共110页使用设计器从里到外进行布局,添加必要的弹簧11.应用一个水平布局管理第56页/共110页使用设计器从里到外进行布局,添加必要的弹簧131.选中2个groupbox并进行布局管理,2.添加一个水平弹簧,3.将弹簧和按钮放置进一个布局管理中2第57页/共110页使用设计器进行信号连接(部件之间)12341.转到signalsandslot编辑模式,2.从一个部件拖放鼠标到另一个部件,3.选中signalandslot,4.在connectionsdock中查看结果第58页/共110页使用设计器进行信号连接(到你的代码中)1231.在widgetediting模式中2.右击一个部件并选择Go to slot.3.选择一个信号来连接到你的代码第59页/共110页使用设计器在代码中使用通过ui类成员使用所有部件classWidget:publicQWidget.private:Ui:Widget*ui;voidWidget:memberFunction()ui-pushButton-setText(.);第60页/共110页界面美化1.子类化已有的控件类,重新实现paintEvent()、MouseEvent()等方法;2.子类化QStyle,或者使用已经定义了的QWindowStyle等。3.使用StyleSheet。第61页/共110页样式表(StyleSheet)所有的QWidget类都有一个styleSheet属性以支持跨平台样式样式表是受启发自CSS的它们可以用来进行高亮处理并进行许多小的修改当然也可以用于用户界面的整体修改第62页/共110页样式表为一个单独的部件应用一个样式表的最简单方法是用设计器第63页/共110页样式表想为整个应用程序设定样式,可以使用QApplication:setStyleSheetQLineEditbackground-color:yellowQLineEdit#nameEditbackground-color:yellowQTextEdit,QListViewbackground-color:white;background-image:url(draft.png);background-attachment:scroll;QGroupBoxbackground-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0#E0E0E0,stop:1#FFFFFF);border:2pxsolidgray;border-radius:5px;margin-top:1ex;使用图片在Designer的编辑器中建立这些选择一个类通过对象名选择一个对象第64页/共110页资源文件(qrc)将图标放进一个资源文件中,Qt会将它们内嵌进可执行文件避免调用多文件不需要尝试确定每个特定安装风格下的图标的路径一切都巧妙地在软件构建系统中自适应避免部署的时候出现文件丢失的错误可以将任何东西添加进资源文件中,不仅仅是图标,但一般是不需要修改的文件。第65页/共110页资源文件(qrc)可以轻松的在QtCreator中管理资源文件在路径和文件名前添加:以使用资源或者简单地在设计器的列表中选择一个图标QPixmappm(:/images/logo.png);第66页/共110页Qt的国际化1.确保应用程序是可翻译的:所用用户可见的字符串都使用tr()修饰根据不同的目标语言加载不同的qm的文件。2.即使应用程序目前不需要翻译,也应该为以后的需求留出余地。第67页/共110页Qt国际化步骤1.在代码中使用tr()修饰用户可见的字符串;2.lupdate提取需要翻译的字符串;TRANSLATIONS=spreadsheet_cn.tsspreadsheet_en.ts3.使用linguist工具翻译;4.在程序开始时加载正确的qm文件。第68页/共110页Qt国际化加载qm文件intmain(intargc,char*argv)QApplicationapp(argc,argv);.QTranslatorappTranslator;appTranslator.load(myapp_+QLocale:system().name(),qmPath);app.installTranslator(&appTranslator);.returnapp.exec();第69页/共110页Qt国际化动态语言切换额外的工作:1.语言切换的途径(菜单、按钮等);2.在统一的方法(RetranslateUI()内处理用户可见字符串,并在语言切换时调用该方法。3.实现changeEvent(QEvent*event)方法voidJournalView:changeEvent(QEvent*event)if(event-type()=QEvent:LanguageChange)retranslateUi();QTableWidget:changeEvent(event);第70页/共110页Qt简介Qt的使用Qt深入理解Qt的应用第71页/共110页QObject类QObject是几乎所有Qt类和所有部件(widget)的基类。它包含很多组成Qt的机制事件信号和槽属性内存管理第72页/共110页QObject类QObject是大部分Qt类的基类例外的例子是:类需要作为轻量级的类,例如图元(graphicalprimitives)-QPen、QBrush。数据容器(QString,QList,QChar等)需要可复制的类,因为QObject类是无法被复制的。第73页/共110页QObject类它们可以拥有一个名字(QObject:objectName)addButton,lineEdit_Password.它们被放置在QObject实例的一个层次上它们可以有到其他QObject实例的联接“QObject 的实例是单独的!”第74页/共110页对象数据存储(1)classPersonprivate:stringmszName;/姓名boolmbSex;/性别intmnAge;/年龄;c+中定义数据变量的一般方法:第75页/共110页/Filename:person.h/声明私有数据成员类型structPersonalDataPrivate;classPersonpublic:Person();/constructorvirtualPerson();/destructorvoidsetAge(constint);intgetAge();private:PersonalDataPrivate*d;对象数据存储(2)Qt定义数据变量(Qt2.x):/Filename:person.cppstructPersonalDataPrivate/定义私有数据成员类型stringmszName;/姓名boolmbSex;/性别intmnAge;/年龄;/constructorPerson:Person()d=newPersonalDataPrivate;/destructorPerson:Person()deleted;voidPerson:setAge(constintage)if(age!=d-mnAge)d-mnAge=age;intPerson:getAge()returnd-mnAge;第76页/共110页元对象系统(Meta-Object System)QObject类作为每一个需要利用元对象系统的类的基类。Q_OBJECT宏,定义在每一个类的私有数据段,用来启用元对象功能,比如,动态属性,信号和槽。元对象编译器moc(theMetaObjectComplier)第77页/共110页元对象系统(Meta-Object System)元对象系统的功能:元数据(QObject:metaObject)类名(QObject:className)继承(QObject:inherits)属性(setProperty和QObject:property)信号和槽(Signalandslot)普通信息(QObject:classInfo)国际化(tr(),QObject:trUtf8()第78页/共110页元对象系统(Meta-Object System)sources*.cppexecutablesobjectfiles*.oheaders*.h普通的普通的C+生成过程生成过程includescompileslinks第79页/共110页元数据通过元对象编译器(moc)在编译时组合在一起,元对象编译器用来处理Qt的C+扩展。moc从头文件里面获得数据。sources*.cppexecutablesobjectfiles*.oheaders*.hgeneratedmoc_*.cppQt C+生成过程生成过程includescompileslinkscompilesmocs元对象系统(Meta-ObjectSystem)第80页/共110页元数据moc找什么?classMyClass:publicQObjectQ_OBJECT Q_CLASSINFO(author,John Doe)public:MyClass(constFoo&foo,QObject*parent=0);Foofoo()const;publicslots:voidsetFoo(constFoo&foo);signals:voidfooChanged(Foo);private:Foom_foo;Qt关键字类的一般信息Q_OBJECT宏,通常是第一步首先确认该类继承自Qobject(可能是间接)第81页/共110页内省(Introspection)类在运行时了解它们自己的信息对实现脚本和动态语言的绑定有很好的支持。if(object-inherits(QAbstractItemView)QAbstractItemView*view=static_cast(widget);view-.enumCapitalsEnumOslo,Helsinki,Stockholm,Copenhagen;intindex=object-metaObject()-indexOfEnumerator(CapitalsEnum);object-metaObject()-enumerator(index)-key(object-capital();能够实现动态转换而不需要运行时类型检查(RTTI)例子:它可以将枚举值转换成更容易阅读和保存的字符串元对象了解细节第82页/共110页属性(Properties)QObject有getter和setter函数属性命名策略:color,setColor对于布尔:isEnabled,setEnabledclassQLabel:publicQFrameQ_OBJECTQ_PROPERTY(QStringtextREADtextWRITEsetText)public:QStringtext()const;publicslots:voidsetText(constQString&);Setter,返回空,将值当成唯一参数Getter,常量,返回值,没有参数第83页/共110页属性为什么使用setter函数?可以验证设置对可能的变化作出反应voidsetMin(intnewMin)if(newMinm_max)qWarning(IgnoringsetMin(%d)asminmax.,newMin);return;.voidsetMin(intnewMin).m_min=newMin;updateMinimum();第84页/共110页属性Properties为什么使用getter函数?间接的属性QSizesize()constreturnm_size;intwidth()constreturnm_size.width();第85页/共110页属性Q_PROPERTY(typenameREADgetFunctionWRITEsetFunctionRESETresetFunctionNOTIFYnotifySignalDESIGNABLEboolSCRIPTABLEboolSTOREDboolUSERboolCONSTANTFINAL)第86页/共110页使用属性直接获取通过元信息和属性系统在运行时发现属性QStringtext=label-text();label-setText(HelloWorld!);QStringtext=object-property(text).toString();object-setProperty(text,HelloWorld);intQMetaObject:propertyCount();QMetaPropertyQMetaObject:property(i);QMetaProperty:name/isConstant/isDesignable/read/write/.第87页/共110页动态属性在运行时给对象增加属性可以用来“标识”对象,等等。boolret=object-setProperty(name,value);QObject:dynamicPropertyNames()const真:如果属性经过真:如果属性经过Q_PROPERTY定义假:如果只是动态增加假:如果只是动态增加返回一个动态属性的列表第88页/共110页创建自定义属性classAngleObject:publicQObjectQ_OBJECTQ_PROPERTY(qrealangleREADangleWRITEsetAngle)public:AngleObject(qrealangle,QObject*parent=0);qrealangle()const;voidsetAngle(qreal);private:qrealm_angle;宏,描述属性初始化值GetterSetter私有状态第89页/共110页创建自定义属性AngleObject:AngleObject(qrealangle,QObject*parent):QObject(parent),m_angle(angle)qrealAngleObject:angle()constreturnm_angle;voidAngleObject:setAngle(qrealangle)m_angle=angle;doSomething();初始化值Getter简单返回值。这里你可以计算复杂的值。更新内部状态,对变化作出反应。第90页/共110页自定义属性-枚举classAngleObject:publicQObjectQ_OBJECTQ_ENUMS(AngleMode)Q_PROPERTY(AngleModeangleModeREAD.)public:enumAngleModeRadians,Degrees;.;普通枚举声明。宏通知QtAngleMode是一个枚举类型。属性使用枚举作为类型。第91页/共110页内存管理QObject可以有父对象和子对象当一个父对象被删除,它的子对象也同样被删除。QObject*parent=newQObject();QObject*child1=newQObject(parent);QObject*child2=newQObject(parent);QObject*child1