NOKIA_QT培训资料(中文版)(共61张).pptx

上传人:醉**** 文档编号:8018959 上传时间:2022-03-11 格式:PPTX 页数:61 大小:1.67MB
返回 下载 相关 举报
NOKIA_QT培训资料(中文版)(共61张).pptx_第1页
第1页 / 共61页
NOKIA_QT培训资料(中文版)(共61张).pptx_第2页
第2页 / 共61页
点击查看更多>>
资源描述

《NOKIA_QT培训资料(中文版)(共61张).pptx》由会员分享,可在线阅读,更多相关《NOKIA_QT培训资料(中文版)(共61张).pptx(61页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、.Qt的对象模型和信号槽的概念Qt in EducationThis work is a Chinese translation of the original Qt Educational Training Materials published by Nokia: 2010 Nokia Corporation and its Subsidiary(-ies).Nokia, Qt and the Nokia and Qt logos are the registered trademarks of Nokia Corporation in Finland and other countrie

2、s worldwide.This translation was created by Communication and Computer Network Laboratory of Guangdong Province, South China University of Technology. 2010 Communication and Computer Network Laboratory of Guangdong Province, South China University of Technology.The enclosed Qt Educational Training M

3、aterials are provided under the Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement. The full license text is available here: http:/creativecommons.org/licenses/by-nc-sa/2.5/legalcode. 此文档内容是由诺基亚公司发布的原创Qt教育培训文档的中文翻译: 2010诺基亚公司及其附属公司。Nokia (诺基亚),Qt以及Nokia与Qt商标是Nokia公司在芬兰和全球其

4、他国家的注册商标。 该翻译版本由 华南理工大学广东省计算机网络重点实验室 创造。 2010 华南理工大学广东省计算机网络重点实验室 本Qt 教育培训材料依照署名-非商业性使用-相同方式共享 2.5许可协议(Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement)发布。 完整的许可证文本可以在这里找到:http:/creativecommons.org/licenses/by-nc-sa/2.5/legalcode。 QObject类QObject是几乎所有Qt类和所有部件(widget)的基类。

5、它包含很多组成Qt的机制事件信号和槽属性内存管理QObject类QObject 是大部分Qt 类的基类例外的例子是:类需要作为轻量级的类,例如图元(graphical primitives)。数据容器(QString, QList, QChar等)需要可复制的类,因为QObject类是无法被复制的。QObject类它们可以拥有一个名字 (QObject:objectName)它们被放置在QObject实例的一个层次上它们可以有到其他 QObject 实例的联接例子: 在运行时复制一个部件有意义吗?“QObject 的实例是单独的!”元数据(Meta data)Qt用C+实现内省每一个 QObj

6、ect 都有一个元对象元对象涉及:类名 (QObject:className)继承 (QObject:inherits)属性信号和槽普通信息(QObject:classInfo)元数据元数据通过元对象编译器(moc)在编译时组合在一起。sources*.cppexecutablesobject files*.oheaders*.h普通的普通的C+生成过程生成过程includescompileslinks元数据Meta data元数据通过元对象编译器(moc)在编译时组合在一起。moc从头文件里面获得数据。sources*.cppexecutablesobject files*.oheaders

7、*.hgeneratedmoc_*.cppQt C+ 生成过程生成过程includescompileslinkscompilesmocs元数据moc 找什么?class MyClass : public QObject Q_OBJECT Q_CLASSINFO(author, John Doe)public: MyClass(const Foo &foo, QObject *parent=0); Foo foo() const;public slots: void setFoo( const Foo &foo );signals: void fooChanged( Foo );private:

8、 Foo m_foo;Qt 关键字类的一般信息 Q_OBJECT宏, 通常是第一步首先确认该类继承自 Qobject (可能是间接)内省(Introspection)类在运行时了解它们自己的信息对实现脚本和动态语言的绑定 有很好的支持。if (object-inherits(QAbstractItemView) QAbstractItemView *view = static_cast(widget); view-.enum CapitalsEnum Oslo, Helsinki, Stockholm, Copenhagen ;int index = object-metaObject()-i

9、ndexOfEnumerator(CapitalsEnum);object-metaObject()-enumerator(index)-key(object-capital();能够实现动态转换而不需要运行时类型检查( RTTI)例子:它可以将枚举值转换成更容易阅读和保存的字符串元对象了解细节属性(Properties)QObject有getter和setter函数属性命名策略: color, setColor对于布尔: isEnabled, setEnabledclass QLabel : public QFrame Q_OBJECT Q_PROPERTY(QString text REA

10、D text WRITE setText)public: QString text() const;public slots: void setText(const QString &);Setter, 返回空,将值当成唯一参数Getter, 常量,返回值,没有参数属性为什么使用setter 函数?可以验证设置对可能的变化作出反应void setMin( int newMin ) if( newMin m_max ) qWarning(Ignoring setMin(%d) as min max., newMin); return; .void setMin( int newMin ) . m

11、_min = newMin; updateMinimum();属性Properties为什么使用getter 函数?间接的属性QSize size() const return m_size;int width() const return m_size.width();属性 Q_PROPERTY(type name READ getFunction WRITE setFunction RESET resetFunction NOTIFY notifySignal DESIGNABLE bool SCRIPTABLE bool STORED bool USER bool CONSTANT FI

12、NAL)使用属性直接获取通过元信息和属性系统在运行时发现属性QString text = label-text();label-setText(Hello World!);QString text = object-property(text).toString();object-setProperty(text, Hello World);int QMetaObject:propertyCount();QMetaProperty QMetaObject:property(i);QMetaProperty:name/isConstant/isDesignable/read/write/.动态属

13、性在运行时给对象增加属性可以用来“标识”对象,等等。bool ret = object-setProperty(name, value);QObject:dynamicPropertyNames() const真:如果属性经过真:如果属性经过Q_PROPERTY 定义 假:如果只是动态增加假:如果只是动态增加返回一个动态属性的列表创建自定义属性class AngleObject : public QObject Q_OBJECT Q_PROPERTY(qreal angle READ angle WRITE setAngle)public: AngleObject(qreal angle, Q

14、Object *parent = 0); qreal angle() const; void setAngle(qreal);private: qreal m_angle;宏,描述属性初始化值GetterSetter私有状态创建自定义属性AngleObject:AngleObject(qreal angle, QObject *parent) : QObject(parent), m_angle(angle)qreal AngleObject:angle() const return m_angle;void AngleObject:setAngle(qreal angle) m_angle

15、= angle; doSomething();初始化值Getter 简单返回值。这里你可以计算复杂的值。更新内部状态, 对变化作出反应。自定义属性 - 枚举class AngleObject : public QObject Q_OBJECT Q_ENUMS(AngleMode) Q_PROPERTY(AngleMode angleMode READ .)public: enum AngleMode Radians, Degrees; .;普通枚举声明。宏通知Qt AngleMode 是一个枚举类型。属性使用枚举作为类型。内存管理QObject 可以有父对象和子对象当一个父对象被删除,它的子对

16、象也同样被删除。QObject *parent = new QObject();QObject *child1 = new QObject(parent);QObject *child2 = new QObject(parent);QObject *child1_1 = new QObject(child1);QObject *child1_2 = new QObject(child1);delete parent;parentchild1child2child1_1child1_2parent 删除 child1 和 child2child1 删除 child1_1 和 child1_2内存

17、管理当需要实现视觉层级时使用到它。QDialog *parent = new QDialog();QGroupBox *box = new QGroupBox(parent);QPushButton *button = new QPushButton(parent);QRadioButton *option1 = new QRadioButton(box);QRadioButton *option2 = new QRadioButton(box);delete parent;parent 删除 box 和 buttonbox 删除 option1 和 option2使用模式使用 this指针指

18、向最高层父对象在栈上分配父对象空间void Widget:showDialog() Dialog dialog; 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

19、(box); .dialog 在作用范围结束时被删除堆(Heap)当使用 new 和 delete时, 内存在堆中分配。堆内存空间必须通过 delete 完全释放,以防止内存泄漏。只要有需要,分配在堆上的对象可以一直存活下去。newdelete构造构造Construction析构析构Destruction栈(Stack)局部变量在栈上分配。栈变量超过作用范围时会自动释放。分配在栈中的对象在超出作用范围时总是会被析构。int a构造构造Construction析构析构Destruction堆 和 栈想要自动内存管理,只有父对象需要在栈上分配。MyMainWindowQApplicationint

20、 main(int argc, char *argv) QApplication a(argc, argv); MyMainWindow w; w.show(); return a.exec();MyMainWindow:MyMainWindow(. new QLabel(this); new .改变所有者QObject可以修改它所属的父对象。父对象知道何时子对象被删除一系列函数实现返回指针,从其所有者“拿走”释放的数据,把它留给拿取者处理obj-setParent(newParent);delete listWidget-item(0); / 删除第一个item(不安全)QLayoutIte

21、m *QLayout:takeAt(int);QListWidgetItem *QListWidget:takeItem(int);/ Safe alternativeQListWidgetItem *item = listWidget-takeItem(0);if (item) delete item; item列表本质上并不是子对象,而是拥有者。 这个例子进行了说明。构造规范几乎所有的 QObject 都有一个默认为空值的父对象。Qwidget 的父对象是其它 QWidget类为了方便倾向于提供多种构造(包括只带有父对象的一种)父对象通常是带缺省值的第一个参数。 QLabel(const

22、QString &text, QWidget *parent=0, Qt:WindowFlags f=0);QObject(QObject *parent=0);QPushButton(QWidget *parent=0);QPushButton(const QString &text, QWidget *parent=0);QPushButton(const QIcon &icon, const QString &text, QWidget *parent=0);构造规范当创建自己的 Qobject时, 需考虑总是允许父对象 parent 为 0 (null)有一个只接受父对象的构造函数pa

23、rent 是带默认值的第一个参数提供几种构造函数,避免空值、无效值(e.g. QString()作为参数。休息信号(signal)和槽(slot)通过反馈的方式动态地或松散地将事件和状态变化联系起来。是什么使 Qt 运作?动作中的信号和槽emit clicked();动作中的信号和槽private slots: void on_addButton_clicked(); void on_deleteButton_clicked();connect(clearButton,SIGNAL(clicked(),listWidget,SLOT(clear();connect(addButton,SIGN

24、AL(clicked(),this,SLOT(.);2xclear();动作中的信号和槽 . emit clicked(); . . emit clicked(); . . emit clicked(); . QString newText = QInputDialog:getText(this, Enter text, Text:); if( !newText.isEmpty() ) ui-listWidget-addItem(newText); foreach (QListWidgetItem *item, ui-listWidget-selectedItems() delete item

25、; clear();信号和槽 vs 回调回调(callback)是一个函数指针,当一个事件发生时被调用,任何函数都可以被安排作为回调。没有类型安全总是以直接调用方式工作信号和槽的方式更加动态一个更通用的机制更容易互连两个已存在的类相关类之间涉及更少的知识共享什么是槽?槽在各种槽段(section)中定义。槽可以返回值,但并不是通过联接。任何数量的信号可以关联到一个槽。它以一个普通的函数实现。它可以作为普通函数被调用。public slots: void aPublicSlot();protected slots: void aProtectedSlot();private slots: voi

26、d aPrivateSlot();connect(src, SIGNAL(sig(), dest, SLOT(slt();什么是信号?信号在信号段(section)中定义信号总是返回空信号总是不必实现由moc来提供实现信号可以关联到任意数量的槽上通常产生一个直接调用,但是可以在线程之间作为事件来传递,甚至可以用在套接字之间(使用第三方类) 槽能以任意次序被激发信号使用emit 关键字发射出去。signals: void aSignal();emit aSignal();建立关联QObject:connect( src, SIGNAL( signature ), dest, SLOT( sign

27、ature ) ); ( . )clicked()toggled(bool)setText(QString)textChanged(QString)rangeChanged(int,int)setTitle(QString text)setValue(42)签名由函数名和参数类型组成。不允许有变量名或值。签名由函数名和参数类型组成。不允许有变量名或值。自定义类型降低了可重用性自定义类型降低了可重用性QObject*setItem(ItemClass)建立关联Qt 参数可以忽略,但不能无中生有。SignalsrangeChanged(int,int)rangeChanged(int,int)ra

28、ngeChanged(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()自动关联使用Designer,它很便捷地在接口和用户代码之间提供自动关联。通过调用QMetaObject:connec

29、tSlotsByName触发当命名时考虑重用性比较 on_widget_signal 和 updatePageMarginson_ object name _ signal name ( signal parameters )on_addButton_clicked();on_deleteButton_clicked();on_listWidget_currentItemChanged(QListWidgetItem*,QListWidgetItem*)updatePageMargins可以关联到一定数量信号或直接调用。值同步双向连接 无限循环必须停止 没有信号被发射,除非发生实际的变化。co

30、nnect(dial1, SIGNAL(valueChanged(int), dial2, SLOT(setValue(int);connect(dial2, SIGNAL(valueChanged(int), dial1, SLOT(setValue(int);void QDial:setValue(int v) if(v=m_value) return; .这就是负责发射信号的所有代码在您自己的类中不要忘记它。自定义信号和槽class AngleObject : public QObject Q_OBJECT Q_PROPERTY(qreal angle READ angle WRITE

31、setAngle NOTIFY angleChanged)public: AngleObject(qreal angle, QObject *parent = 0); qreal angle() const;public slots: void setAngle(qreal);signals: void angleChanged(qreal);private: qreal m_angle;在这里添加一个通知信号。setter构造自然槽。信号匹配settersetter实现细节void AngleObject:setAngle(qreal angle) if(m_angle = angle) r

32、eturn; m_angle = angle; emit angleChanged(m_angle);防止无限循环。不要忘记不要忘记!更新内部状态,然后发射信号。信号是被“保护”的,他们可以从派生类发射。温度转换器使用 TempConverter 类实现在摄氏与华氏之间的转换当温度改变时发射信号。温度转换器对话窗口(dialog window)包含以下对象一个 TempConverter 实例两个 QGroupBox 部件(widget), 每一个包含一个 QDial 部件一个 QLCDNumber 部件温度转换器class TempConverter : public QObject Q_O

33、BJECT public: TempConverter(int tempCelsius, QObject *parent = 0); int tempCelsius() const; int tempFahrenheit() const;public slots: void setTempCelsius(int); void setTempFahrenheit(int);signals: void tempCelsiusChanged(int); void tempFahrenheitChanged(int);private: int m_tempCelsius;先是Q_OBJECT 宏QOb

34、ject 作为父对象父对象指针读和写函数当温度变化时发射信号。在内部表示整数摄氏度。温度转换器void TempConverter:setTempCelsius(int tempCelsius) if(m_tempCelsius = tempCelsius) return; m_tempCelsius = tempCelsius; emit tempCelsiusChanged(m_tempCelsius); emit tempFahrenheitChanged(tempFahrenheit();void TempConverter:setTempFahrenheit(int tempFahr

35、enheit) int tempCelsius = (5.0/9.0)*(tempFahrenheit-32); setTempCelsius(tempCelsius);setTempCelsius槽:setTempFahrenheit槽:测试改变以中断递归更新对象的状态发射信号反映改变转换,传递摄氏度是内部表现形式。温度转换器表盘通过 TempConverter 联系起来LCD 显示直接受表盘来驱动。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged s

36、etTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged(int), tempConverter, SLOT(setTempCelsius(int);connect(celsiusDial, SIGNAL(valueChanged(int), celsiusLcd, SLOT(display(int);connect(tempConv

37、erter, 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(i

38、nt), fahrenheitDial, SLOT(setValue(int);温度转换器用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(

39、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(setTemp

40、Fahrenheit(int);connect(fahrenheitDial, SIGNAL(valueChanged(int), fahrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);温度转换器用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChang

41、ed setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged(int), tempConverter, SLOT(setTempCelsius(int);connect(celsiusDial, SIGNAL(valueChanged(int), celsiusLcd, SLOT(display(int);connect(temp

42、Converter, 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(tempFahrenheitChang

43、ed(int), fahrenheitDial, SLOT(setValue(int);温度转换器用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIG

44、NAL(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(set

45、TempFahrenheit(int);connect(fahrenheitDial, SIGNAL(valueChanged(int), fahrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);温度转换器用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueC

46、hanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged(int), tempConverter, SLOT(setTempCelsius(int);connect(celsiusDial, SIGNAL(valueChanged(int), celsiusLcd, SLOT(display(int);connect(

47、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(tempFahrenheitC

48、hanged(int), fahrenheitDial, SLOT(setValue(int);温度转换器用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial,

49、 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

50、(setTempFahrenheit(int);connect(fahrenheitDial, SIGNAL(valueChanged(int), fahrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);温度转换器用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedva

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁