NOKIA-QT培训资料PPT课件_第1页
NOKIA-QT培训资料PPT课件_第2页
NOKIA-QT培训资料PPT课件_第3页
NOKIA-QT培训资料PPT课件_第4页
NOKIA-QT培训资料PPT课件_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,-,.,Qt的对象模型和信号槽的概念,QtinEducation,2,-,ThisworkisaChinesetranslationoftheoriginalQtEducationalTrainingMaterialspublishedbyNokia:2010NokiaCorporationanditsSubsidiary(-ies).Nokia,QtandtheNokiaandQtlogosaretheregisteredtrademarksofNokiaCorporationinFinlandandothercountriesworldwide.ThistranslationwascreatedbyCommunicationandComputerNetworkLaboratoryofGuangdongProvince,SouthChinaUniversityofTechnology.2010CommunicationandComputerNetworkLaboratoryofGuangdongProvince,SouthChinaUniversityofTechnology.TheenclosedQtEducationalTrainingMaterialsareprovidedundertheCreativeCommonsAttribution-Non-Commercial-ShareAlike2.5LicenseAgreement.Thefulllicensetextisavailablehere:/licenses/by-nc-sa/2.5/legalcode.,此文档内容是由诺基亚公司发布的原创Qt教育培训文档的中文翻译:2010诺基亚公司及其附属公司。Nokia(诺基亚),Qt以及Nokia与Qt商标是Nokia公司在芬兰和全球其他国家的注册商标。该翻译版本由华南理工大学广东省计算机网络重点实验室创造。2010华南理工大学广东省计算机网络重点实验室本Qt教育培训材料依照署名-非商业性使用-相同方式共享2.5许可协议(CreativeCommonsAttribution-Non-Commercial-ShareAlike2.5LicenseAgreement)发布。完整的许可证文本可以在这里找到:/licenses/by-nc-sa/2.5/legalcode。,3,-,QObject类,QObject是几乎所有Qt类和所有部件(widget)的基类。它包含很多组成Qt的机制事件信号和槽属性内存管理,4,-,QObject类,QObject是大部分Qt类的基类例外的例子是:类需要作为轻量级的类,例如图元(graphicalprimitives)。数据容器(QString,QList,QChar等)需要可复制的类,因为QObject类是无法被复制的。,5,-,QObject类,它们可以拥有一个名字(QObject:objectName)它们被放置在QObject实例的一个层次上它们可以有到其他QObject实例的联接例子:在运行时复制一个部件有意义吗?,“QObject的实例是单独的!”,6,-,元数据(Metadata),Qt用C+实现内省每一个QObject都有一个元对象元对象涉及:类名(QObject:className)继承(QObject:inherits)属性信号和槽普通信息(QObject:classInfo),7,-,元数据,元数据通过元对象编译器(moc)在编译时组合在一起。,sources*.cpp,executables,objectfiles*.o,headers*.h,普通的C+生成过程,includes,compiles,links,8,-,元数据Metadata,元数据通过元对象编译器(moc)在编译时组合在一起。moc从头文件里面获得数据。,sources*.cpp,executables,objectfiles*.o,headers*.h,generatedmoc_*.cpp,QtC+生成过程,includes,compiles,links,compiles,mocs,9,-,元数据,moc找什么?,classMyClass:publicQObjectQ_OBJECTQ_CLASSINFO(author,JohnDoe)public:MyClass(constFoo,10,-,内省(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();,11,-,属性(Properties),QObject有getter和setter函数属性命名策略:color,setColor对于布尔:isEnabled,setEnabled,classQLabel:publicQFrameQ_OBJECTQ_PROPERTY(QStringtextREADtextWRITEsetText)public:QStringtext()const;publicslots:voidsetText(constQString,12,-,属性,为什么使用setter函数?可以验证设置对可能的变化作出反应,voidsetMin(intnewMin)if(newMinm_max)qWarning(IgnoringsetMin(%d)asminmax.,newMin);return;.,voidsetMin(intnewMin).m_min=newMin;updateMinimum();,13,-,属性Properties,为什么使用getter函数?间接的属性,QSizesize()constreturnm_size;intwidth()constreturnm_size.width();,14,-,属性,Q_PROPERTY(typenameREADgetFunctionWRITEsetFunctionRESETresetFunctionNOTIFYnotifySignalDESIGNABLEboolSCRIPTABLEboolSTOREDboolUSERboolCONSTANTFINAL),15,-,使用属性,直接获取通过元信息和属性系统在运行时发现属性,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/.,16,-,动态属性,在运行时给对象增加属性可以用来“标识”对象,等等。,boolret=object-setProperty(name,value);,QObject:dynamicPropertyNames()const,17,-,创建自定义属性,classAngleObject:publicQObjectQ_OBJECTQ_PROPERTY(qrealangleREADangleWRITEsetAngle)public:AngleObject(qrealangle,QObject*parent=0);qrealangle()const;voidsetAngle(qreal);private:qrealm_angle;,18,-,创建自定义属性,AngleObject:AngleObject(qrealangle,QObject*parent):QObject(parent),m_angle(angle)qrealAngleObject:angle()constreturnm_angle;voidAngleObject:setAngle(qrealangle)m_angle=angle;doSomething();,19,-,自定义属性-枚举,classAngleObject:publicQObjectQ_OBJECTQ_ENUMS(AngleMode)Q_PROPERTY(AngleModeangleModeREAD.)public:enumAngleModeRadians,Degrees;.;,20,-,内存管理,QObject可以有父对象和子对象当一个父对象被删除,它的子对象也同样被删除。,QObject*parent=newQObject();QObject*child1=newQObject(parent);QObject*child2=newQObject(parent);QObject*child1_1=newQObject(child1);QObject*child1_2=newQObject(child1);deleteparent;,parent,child1,child2,child1_1,child1_2,21,-,内存管理,当需要实现视觉层级时使用到它。,QDialog*parent=newQDialog();QGroupBox*box=newQGroupBox(parent);QPushButton*button=newQPushButton(parent);QRadioButton*option1=newQRadioButton(box);QRadioButton*option2=newQRadioButton(box);deleteparent;,22,-,使用模式,使用this指针指向最高层父对象在栈上分配父对象空间,voidWidget:showDialog()Dialogdialog;if(dialog.exec()=QDialog:Accepted).,Dialog:Dialog(QWidget*parent):QDialog(parent)QGroupBox*box=QGroupBox(this);QPushButton*button=QPushButton(this);QRadioButton*option1=QRadioButton(box);QRadioButton*option2=QRadioButton(box);.,23,-,堆(Heap),当使用new和delete时,内存在堆中分配。堆内存空间必须通过delete完全释放,以防止内存泄漏。只要有需要,分配在堆上的对象可以一直存活下去。,new,delete,构造Construction,析构Destruction,24,-,栈(Stack),局部变量在栈上分配。栈变量超过作用范围时会自动释放。分配在栈中的对象在超出作用范围时总是会被析构。,inta,构造Construction,析构Destruction,25,-,堆和栈,想要自动内存管理,只有父对象需要在栈上分配。,MyMainWindow,QApplication,intmain(intargc,char*argv)QApplicationa(argc,argv);MyMainWindoww;w.show();returna.exec();,MyMainWindow:MyMainWindow(.newQLabel(this);new.,26,-,改变所有者,QObject可以修改它所属的父对象。父对象知道何时子对象被删除一系列函数实现返回指针,从其所有者“拿走”释放的数据,把它留给拿取者处理,obj-setParent(newParent);,deletelistWidget-item(0);/删除第一个item(不安全),QLayoutItem*QLayout:takeAt(int);QListWidgetItem*QListWidget:takeItem(int);/SafealternativeQListWidgetItem*item=listWidget-takeItem(0);if(item)deleteitem;,27,-,构造规范,几乎所有的QObject都有一个默认为空值的父对象。Qwidget的父对象是其它QWidget类为了方便倾向于提供多种构造(包括只带有父对象的一种)父对象通常是带缺省值的第一个参数。,QLabel(constQString,QObject(QObject*parent=0);,QPushButton(QWidget*parent=0);QPushButton(constQString,28,-,构造规范,当创建自己的Qobject时,需考虑总是允许父对象parent为0(null)有一个只接受父对象的构造函数parent是带默认值的第一个参数提供几种构造函数,避免空值、无效值(e.g.QString()作为参数。,29,-,休息,30,-,信号(signal)和槽(slot),通过反馈的方式动态地或松散地将事件和状态变化联系起来。是什么使Qt运作?,31,-,动作中的信号和槽,emitclicked();,32,-,动作中的信号和槽,privateslots:voidon_addButton_clicked();voidon_deleteButton_clicked();,connect(clearButton,SIGNAL(clicked(),listWidget,SLOT(clear();,connect(addButton,SIGNAL(clicked(),this,SLOT(.);,2x,clear();,33,-,动作中的信号和槽,.emitclicked();.,.emitclicked();.,.emitclicked();.,QStringnewText=QInputDialog:getText(this,Entertext,Text:);if(!newText.isEmpty()ui-listWidget-addItem(newText);,foreach(QListWidgetItem*item,ui-listWidget-selectedItems()deleteitem;,clear();,34,-,信号和槽vs回调,回调(callback)是一个函数指针,当一个事件发生时被调用,任何函数都可以被安排作为回调。没有类型安全总是以直接调用方式工作信号和槽的方式更加动态一个更通用的机制更容易互连两个已存在的类相关类之间涉及更少的知识共享,35,-,什么是槽?,槽在各种槽段(section)中定义。槽可以返回值,但并不是通过联接。任何数量的信号可以关联到一个槽。它以一个普通的函数实现。它可以作为普通函数被调用。,publicslots:voidaPublicSlot();protectedslots:voidaProtectedSlot();privateslots:voidaPrivateSlot();,connect(src,SIGNAL(sig(),dest,SLOT(slt();,36,-,什么是信号?,信号在信号段(section)中定义信号总是返回空信号总是不必实现由moc来提供实现信号可以关联到任意数量的槽上通常产生一个直接调用,但是可以在线程之间作为事件来传递,甚至可以用在套接字之间(使用第三方类)槽能以任意次序被激发信号使用emit关键字发射出去。,signals:voidaSignal();,emitaSignal();,37,-,建立关联,QObject:connect(src,SIGNAL(signature),dest,SLOT(signature);,(.),clicked()toggled(bool)setText(QString)textChanged(QString)rangeChanged(int,int),setTitle(QStringtext)setValue(42),签名由函数名和参数类型组成。不允许有变量名或值。,自定义类型降低了可重用性,setItem(ItemClass),38,-,建立关联,Qt参数可以忽略,但不能无中生有。,SignalsrangeChanged(int,int)rangeChanged(int,int)rangeChanged(int,int)valueChanged(int)valueChanged(int)valueChanged(int)textChanged(QString)clicked()clicked(),SlotssetRange(int,int)setValue(int)updateDialog()setRange(int,int)setValue(int)updateDialog()setValue(int)setValue(int)updateDialog(),39,-,自动关联,使用Designer,它很便捷地在接口和用户代码之间提供自动关联。通过调用QMetaObject:connectSlotsByName触发当命名时考虑重用性比较on_widget_signal和updatePageMargins,on_objectname_signalname(signalparameters)on_addButton_clicked();on_deleteButton_clicked();on_listWidget_currentItemChanged(QListWidgetItem*,QListWidgetItem*),40,-,值同步,双向连接无限循环必须停止没有信号被发射,除非发生实际的变化。,voidQDial:setValue(intv)if(v=m_value)return;.,41,-,自定义信号和槽,classAngleObject:publicQObjectQ_OBJECTQ_PROPERTY(qrealangleREADangleWRITEsetAngleNOTIFYangleChanged)public:AngleObject(qrealangle,QObject*parent=0);qrealangle()const;publicslots:voidsetAngle(qreal);signals:voidangleChanged(qreal);private:qrealm_angle;,42,-,setter实现细节,voidAngleObject:setAngle(qrealangle)if(m_angle=angle)return;m_angle=angle;emitangleChanged(m_angle);,43,-,温度转换器,使用TempConverter类实现在摄氏与华氏之间的转换当温度改变时发射信号。,44,-,温度转换器,对话窗口(dialogwindow)包含以下对象一个TempConverter实例两个QGroupBox部件(widget),每一个包含一个QDial部件一个QLCDNumber部件,45,-,温度转换器,classTempConverter:publicQObjectQ_OBJECTpublic:TempConverter(inttempCelsius,QObject*parent=0);inttempCelsius()const;inttempFahrenheit()const;publicslots:voidsetTempCelsius(int);voidsetTempFahrenheit(int);signals:voidtempCelsiusChanged(int);voidtempFahrenheitChanged(int);private:intm_tempCelsius;,46,-,温度转换器,voidTempConverter:setTempCelsius(inttempCelsius)if(m_tempCelsius=tempCelsius)return;m_tempCelsius=tempCelsius;emittempCelsiusChanged(m_tempCelsius);emittempFahrenheitChanged(tempFahrenheit();voidTempConverter:setTempFahrenheit(inttempFahrenheit)inttempCelsius=(5.0/9.0)*(tempFahrenheit-32);setTempCelsius(tempCelsius);,setTempCelsius槽:setTempFahrenheit槽:,47,-,温度转换器,表盘通过TempConverter联系起来LCD显示直接受表盘来驱动。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,48,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,49,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,50,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,51,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,52,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,53,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiusChanged(int),celsiusDial,SLOT(setValue(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempFahrenheit(int);connect(fahrenheitDial,SIGNAL(valueChanged(int),fahrenheitLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempFahrenheitChanged(int),fahrenheitDial,SLOT(setValue(int);,54,-,温度转换器,用户调节摄氏度表盘。,connect(celsiusDial,SIGNAL(valueChanged(int),tempConverter,SLOT(setTempCelsius(int);connect(celsiusDial,SIGNAL(valueChanged(int),celsiusLcd,SLOT(display(int);connect(tempConverter,SIGNAL(tempCelsiu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论