Qt类库和信号槽推荐课件

上传人:桔**** 文档编号:590237868 上传时间:2024-09-13 格式:PPT 页数:94 大小:1.70MB
返回 下载 相关 举报
Qt类库和信号槽推荐课件_第1页
第1页 / 共94页
Qt类库和信号槽推荐课件_第2页
第2页 / 共94页
Qt类库和信号槽推荐课件_第3页
第3页 / 共94页
Qt类库和信号槽推荐课件_第4页
第4页 / 共94页
Qt类库和信号槽推荐课件_第5页
第5页 / 共94页
点击查看更多>>
资源描述

《Qt类库和信号槽推荐课件》由会员分享,可在线阅读,更多相关《Qt类库和信号槽推荐课件(94页珍藏版)》请在金锄头文库上搜索。

1、Qt类库2021/8/221Q Qt t类库架构类库架构2021/8/222Qt类库类库跨平台的跨平台的qt包含了大约包含了大约15个模块个模块接近接近700个个APIs,所有的模块都依赖于所有的模块都依赖于QtCore特殊情况,有特殊情况,有3个模块依赖具体的平台个模块依赖具体的平台:QAxContainer、QAxServer、QtDBus2021/8/2232021/8/224Qt类库(续)类库(续)库描述描述QtCoreQtCoreQtCoreQtCore核心非核心非核心非核心非GUIGUI功能功能功能功能QtGuiQtGuiQtGuiQtGui核心核心核心核心GUIGUI功能功能功能

2、功能QtNetworkQtNetworkQtNetworkQtNetwork网网网网络络模模模模块块QtOpenGLQtOpenGLQtOpenGLQtOpenGLOpenGLOpenGL模模模模块块( (为为三三三三维绘图维绘图提供的提供的提供的提供的标标准准准准应应用用用用编编程接口程接口程接口程接口) )QtSqlQtSqlQtSqlQtSqlSQLSQL模模模模块块QtSvgQtSvgQtSvgQtSvgSVGSVG透透透透视图类视图类QtXmlQtXmlQtXmlQtXmlXMLXML模模模模块块Qt3SupportQt3SupportQt3SupportQt3Support支持支持

3、支持支持Qt3Qt3的的的的类类QAxContainerQAxContainerQAxContainerQAxContainerActiveQt ActiveQt ActiveQt ActiveQt 客客客客户户端的端的端的端的扩扩充充充充QAxServerQAxServerQAxServerQAxServerActiveQtActiveQtActiveQtActiveQt 服服服服务务器段的器段的器段的器段的扩扩充充充充QtAssistantQtAssistantQtAssistantQtAssistantQtQt助手的助手的助手的助手的语语言言言言类类QtDesignerQtDesigne

4、rQtDesignerQtDesignerQtQt设计设计器的器的器的器的扩扩展展展展类类QtUiToolsQtUiToolsQtUiToolsQtUiTools生成生成生成生成动态动态GUIGUI类类QtTestQtTestQtTestQtTest单单元元元元测试测试工具工具工具工具类类5Qt主要基类2021/8/226QObject类类Qt对象模型的核心对象模型的核心QObject类类是几乎所有是几乎所有Qt类和所有部件类和所有部件(widget)的基类的基类所有的所有的QWidgets都是都是QObject提供对象树和对象的关系提供对象树和对象的关系QObject在整个在整个Qt的体系中

5、处于一个非常重要的位置的体系中处于一个非常重要的位置提供了信号提供了信号-槽的通信机制槽的通信机制对象不允许拷贝(禁用拷贝构造)对象不允许拷贝(禁用拷贝构造)包含了很多组成包含了很多组成Qt的机制的机制事件处理事件处理内存管理内存管理属性,内省(属性,内省(Introspection)2021/8/227元数据(元数据(Metadata)Qt用用C+实现内省(实现内省(Introspection)每一个每一个QObject都有一个元对象都有一个元对象元对象涉及:元对象涉及:类名类名(QObject:className)继承继承(QObject:inherits)属性属性信号和槽信号和槽普通信息

6、普通信息(QObject:classInfo)2021/8/228元数据元数据元数据通过元对象编译器元数据通过元对象编译器(moc)在编译时组在编译时组合在一起。合在一起。sources*.cppexecutablesobject files*.oheaders*.h普通的普通的C+生成过程生成过程includescompileslinks2021/8/229元数据元数据Metadata元数据通过元对象编译器元数据通过元对象编译器(moc)在编译时组在编译时组合在一起。合在一起。moc从头文件里面获得数据。从头文件里面获得数据。sources*.cppexecutablesobject fil

7、es*.oheaders*.hgeneratedmoc_*.cppQtC+生成过程生成过程includescompileslinkscompilesmocs2021/8/2210元数据元数据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

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

9、 Oslo, Helsinki, Stockholm, Copenhagen ;int index = object-metaObject()-indexOfEnumerator(CapitalsEnum);object-metaObject()-enumerator(index)-key(object-capital();能够实现动态转换而不需要运行时类型检查( RTTI)例子:它可以将枚举值转换成更容易阅读和保存的字符串元对象了解细节2021/8/2212属性属性(Properties)QObject有有getter和和setter函数属性函数属性命名策略命名策略:color,setCol

10、or对于布尔类型对于布尔类型:isEnabled,setEnabledclass QLabel : public QFrame Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText)public: QString text() const;public slots: void setText(const QString &);Setter, 返回空,将值当成唯一参数Getter, 常量,返回值,没有参数2021/8/2213属性属性为什么使用为什么使用setter函数?函数?可以验证设置可以验证设置对可能的变化作出反应对可能的变化作出

11、反应void setMin( int newMin ) if( newMin m_max ) qWarning(Ignoring setMin(%d) as min max., newMin); return; .void setMin( int newMin ) . m_min = newMin; updateMinimum();2021/8/2214属性属性为什么使用为什么使用getter函数?函数?间接的属性间接的属性QSize size() const return m_size;int width() const return m_size.width();2021/8/2215属性

12、属性 Q_PROPERTY(type name READ getFunction WRITE setFunction RESET resetFunction NOTIFY notifySignal DESIGNABLE bool SCRIPTABLE bool STORED bool USER bool CONSTANT FINAL)属性跟类中数据成员的主要区别属性跟类中数据成员的主要区别必须有一个必须有一个read函数函数有一个可选的有一个可选的write函数函数如果定义了如果定义了stored属性表明这是一属性表明这是一直存在的。直存在的。一个一个reset函数能够把函数能够把proper

13、ty设置设置成其默认状态成其默认状态一个一个desinable属性表明该属性表明该property能在能在GUIbuilder(一般为一般为QtDesigner)可见可见2021/8/2216使用属性使用属性直接获取直接获取通过元信息和属性系统通过元信息和属性系统在运行时发现属性在运行时发现属性QString text = label-text();label-setText(Hello World!);QString text = object-property(text).toString();object-setProperty(text, Hello World);int QMetaO

14、bject:propertyCount();QMetaProperty QMetaObject:property(i);QMetaProperty:name/isConstant/isDesignable/read/write/.2021/8/2217动态属性动态属性在运行时给对象增加属性在运行时给对象增加属性可以用来可以用来“标识标识”对象,等等。对象,等等。bool ret = object-setProperty(name, value);QObject:dynamicPropertyNames() const真:如果属性经过真:如果属性经过Q_PROPERTY 定义 假:如果只是动态增

15、加假:如果只是动态增加返回一个动态属性的列表2021/8/2218创建自定义属性创建自定义属性class AngleObject : public QObject Q_OBJECT Q_PROPERTY(qreal angle READ angle WRITE setAngle)public: AngleObject(qreal angle, QObject *parent = 0); qreal angle() const; void setAngle(qreal);private: qreal m_angle;宏,描述属性初始化值GetterSetter私有状态2021/8/2219创建自

16、定义属性创建自定义属性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 = angle; doSomething();初始化值Getter 简单返回值。这里你可以计算复杂的值。更新内部状态, 对变化作出反应。2021/8/2220自定义属性自定义属性-枚举枚举class AngleObj

17、ect : public QObject Q_OBJECT Q_ENUMS(AngleMode) Q_PROPERTY(AngleMode angleMode READ .)public: enum AngleMode Radians, Degrees; .;普通枚举声明。宏通知Qt AngleMode 是一个枚举类型。属性使用枚举作为类型。2021/8/2221QObject类(续)类(续)-父子关系父子关系每一个每一个QObject对象都可以有一个指向父亲的参数对象都可以有一个指向父亲的参数孩子会通知他的父亲自己的存在,父亲会把它加入到自己孩子会通知他的父亲自己的存在,父亲会把它加入到自己

18、的孩子列表中的孩子列表中如果一个如果一个widget对象没有父亲,那么他就是一个窗口对象没有父亲,那么他就是一个窗口父部件可以父部件可以:当父部件隐藏或显示自己的时候,会自动的隐藏和显示子部件当父部件隐藏或显示自己的时候,会自动的隐藏和显示子部件当父部件当父部件enable和和disable时,子部件的状态也随之变化时,子部件的状态也随之变化注意:在父部件可见的时候,子部件也可以单独隐藏自己注意:在父部件可见的时候,子部件也可以单独隐藏自己2021/8/2222改变所有者改变所有者QObject可以修改它所属的父对象。可以修改它所属的父对象。父对象知道何时子对象被删除父对象知道何时子对象被删除

19、一系列函数实现返回指针,从其所有者一系列函数实现返回指针,从其所有者“拿走拿走”释放的数据,释放的数据,把它留给拿取者处理把它留给拿取者处理obj-setParent(newParent);delete listWidget-item(0); / 删除第一个item(不安全)QLayoutItem *QLayout:takeAt(int);QListWidgetItem *QListWidget:takeItem(int);/ Safe alternativeQListWidgetItem *item = listWidget-takeItem(0);if (item) delete item

20、; item列表本质上并不是子对象,而是拥有者。 这个例子进行了说明。2021/8/2223QObject类(续)类(续)-内存管理内存管理所有子对象的内存管理都转移给了父对象所有子对象的内存管理都转移给了父对象使用使用new在堆上分配内存在堆上分配内存子对象可自动被父对象删除内存子对象可自动被父对象删除内存手动删除不会引起二次删除,因为子对象删除时会通知父对象手动删除不会引起二次删除,因为子对象删除时会通知父对象没有父对象的没有父对象的QObject对象都需要手动删除对象都需要手动删除一般把这种无父亲的对象分配在栈上,可以避免内存泄露的问题一般把这种无父亲的对象分配在栈上,可以避免内存泄露的

21、问题Qt是否有类似于自动回收站的机制?但是事实是没有的是否有类似于自动回收站的机制?但是事实是没有的!只需要关注对象的父子关系和功能只需要关注对象的父子关系和功能!2021/8/2224内存管理内存管理QObject可以有父对象和子对象可以有父对象和子对象当一个父对象被删除,它的子对象也同样被删除。当一个父对象被删除,它的子对象也同样被删除。QObject *parent = new QObject();QObject *child1 = new QObject(parent);QObject *child2 = new QObject(parent);QObject *child1_1 =

22、new QObject(child1);QObject *child1_2 = new QObject(child1);delete parent;parentchild1child2child1_1child1_2parent 删除 child1 和 child2child1 删除 child1_1 和 child1_22021/8/2225内存管理内存管理当需要实现视觉层级时使用到它。当需要实现视觉层级时使用到它。QDialog *parent = new QDialog();QGroupBox *box = new QGroupBox(parent);QPushButton *butto

23、n = new QPushButton(parent);QRadioButton *option1 = new QRadioButton(box);QRadioButton *option2 = new QRadioButton(box);delete parent;parent 删除 box 和 buttonbox 删除 option1 和 option22021/8/2226使用模式使用模式使用使用this指针指向最高层父对象指针指向最高层父对象在栈上分配父对象空间在栈上分配父对象空间void Widget:showDialog() Dialog dialog; if (dialog.ex

24、ec() = QDialog:Accepted) . Dialog:Dialog(QWidget *parent) : QDialog(parent) QGroupBox *box = QGroupBox(this); QPushButton *button = QPushButton(this); QRadioButton *option1 = QRadioButton(box); QRadioButton *option2 = QRadioButton(box); .dialog 在作用范围结束时被删除2021/8/2227堆(堆(Heap)当使用当使用new和和delete时时,内存在堆

25、中分配。内存在堆中分配。堆内存空间必须通过堆内存空间必须通过delete完全释放,以防止完全释放,以防止内存泄漏。内存泄漏。只要有需要,分配在堆上只要有需要,分配在堆上的对象可以一直存活下去。的对象可以一直存活下去。newdelete构造构造Construction析构析构Destruction2021/8/2228栈(栈(Stack)局部变量在栈上分配。局部变量在栈上分配。栈变量超过作用范围时会自栈变量超过作用范围时会自动释放。动释放。分配在栈中的对象在超出作分配在栈中的对象在超出作用范围时总是会被析构。用范围时总是会被析构。int a构造构造Construction析构析构Destruct

26、ion2021/8/2229堆和栈堆和栈想要自动内存管理,只有父对象需要想要自动内存管理,只有父对象需要在栈上分配。在栈上分配。MyMainWindowQApplicationint main(int argc, char *argv) QApplication a(argc, argv); MyMainWindow w; w.show(); return a.exec();MyMainWindow:MyMainWindow(. new QLabel(this); new .2021/8/2230QObject类(续)类(续)-创建对象创建对象从从QObject继承的对象都使用继承的对象都使用

27、new在堆上分配空间在堆上分配空间如果创建对象的时候设置了父对象,父对象就负责管理新创建的如果创建对象的时候设置了父对象,父对象就负责管理新创建的对象对象QLabel*label=newQLabel(”SomeText”,parent);没有从没有从QObject继承的对象则分配在栈上,而不是堆上继承的对象则分配在栈上,而不是堆上QStringListlist;QColorcolor;例外例外QFile和和QApplication(继承继承QObject)通常分配在栈上通常分配在栈上模式对话框常常分配在栈上模式对话框常常分配在栈上2021/8/2231构造规范构造规范几乎所有的几乎所有的QOb

28、ject都有一个默认为空值的父对象。都有一个默认为空值的父对象。QWidget的父对象是其它的父对象是其它QWidget类类为了方便倾向于提供多种构造(包括只带有父对象的一种)为了方便倾向于提供多种构造(包括只带有父对象的一种)父对象通常是带缺省值的第一个参数。父对象通常是带缺省值的第一个参数。QLabel(const QString &text, QWidget *parent=0, Qt:WindowFlags f=0);QObject(QObject *parent=0);QPushButton(QWidget *parent=0);QPushButton(const QString &

29、text, QWidget *parent=0);QPushButton(const QIcon &icon, const QString &text, QWidget *parent=0);2021/8/2232构造规范构造规范当创建自己的当创建自己的QObject时时,需考虑需考虑总是允许父对象总是允许父对象parent为为0(null)有一个只接受父对象的构造函数有一个只接受父对象的构造函数parent是带默认值的第一个参数是带默认值的第一个参数提供几种构造函数,避免空值、无效值提供几种构造函数,避免空值、无效值(e.g.QString()作为参数。作为参数。2021/8/2233QOb

30、ject类对象类对象QObject类是所有能够处理类是所有能够处理signal、slot和事件的和事件的Qt对对象的基类,原形如下:象的基类,原形如下:QObject:QObject(QObject*parent=0,constchar*name=0)创建带有父对象及其名字的对象,对象的父对象可以看创建带有父对象及其名字的对象,对象的父对象可以看作这个对象的所有者。比如,对话框是其中的作这个对象的所有者。比如,对话框是其中的ok和和cancel按钮的父对象。按钮的父对象。在上面的函数中如果在上面的函数中如果parent为为0则构造一个无父的对象,则构造一个无父的对象,如果对象是一个组件,则它就

31、会成为顶层的窗口。如果对象是一个组件,则它就会成为顶层的窗口。2021/8/2234QObject类(实例)类(实例)class Mandelbrot:public QObjectQ_OBJECT /需要使用需要使用signal和和slotpublic :Mandelbrot(QObect *parent=0, const char *name);public slots:void start();signals:void done();private slots:void calculate();private:QTimer timer;;2021/8/2235QObject类(实例)类(实

32、例)/构造初始化一个构造初始化一个Mandelbrot对象对象Mandelbrot:Mandelbrot(QObject *parent=0, const char *name):QObject(parent, name)connect(&timer,SIGNAL(timeout(),SLOT(calculate();2021/8/2236QApplication类类QApplication类负责类负责GUI应用程序的控制流和应用程序的控制流和主要的设置,包括:主要的设置,包括:主事件循环体,负责处理和调度所有来自窗口系统主事件循环体,负责处理和调度所有来自窗口系统和其他资源的事件和其他资源的

33、事件处理应用程序的开始、结束以及会话管理处理应用程序的开始、结束以及会话管理还包括系统和应用程序方面的设置还包括系统和应用程序方面的设置对于一个应用程序来说,建立对于一个应用程序来说,建立QApplication类类的对象是必不可少的的对象是必不可少的QApplication是是QObject类的子类类的子类2021/8/2237函数分函数分组 系统设置 desktopSettingsAware()、setDesktopSettingsAware()、cursorFlashTime()、setCursorFlashTime()、doubleClickInterval()、setDoubleCl

34、ickInterval()、wheelScrollLines()、setWheelScrollLines()、palette()、setPalette()、font()、setFont()、fontMetrics()。 事件处理 exec()、processEvents()、enter_loop()、exit_loop()、exit()、quit()。 sendEvent()、postEvent()、sendPostedEvents()、removePostedEvents()、hasPendingEvents()、notify()、macEventFilter()、qwsEventFilte

35、r()、x11EventFilter()、x11ProcessEvent()、winEventFilter()。 图形用户界面风格 style()、setStyle()、polish()。 颜色使用 colorSpec()、setColorSpec()、qwsSetCustomColors()。 文本处理 setDefaultCodec()、installTranslator()、removeTranslator()、translate()。 窗口部件 mainWidget()、setMainWidget()、allWidgets()、topLevelWidgets()、desktop()、a

36、ctivePopupWidget()、activeModalWidget()、clipboard()、focusWidget()、winFocus()、activeWindow()、widgetAt()。 高级光标处理 hasGlobalMouseTracking()、setGlobalMouseTracking()、overrideCursor()、setOverrideCursor()、restoreOverrideCursor()。 X窗口系统同步 flushX()、syncX()。 对话管理 isSessionRestored()、sessionId()、commitData()、sa

37、veState()。 线程 lock()、unlock()、locked()、tryLock()、wakeUpGuiThread()。 杂项 closeAllWindows()、startingUp()、closingDown()、type()。 38QWidget类类QWidget类是所有用户界面对象的基类,是类是所有用户界面对象的基类,是QObject类的类的子类,继承了子类,继承了QObject类的属性。类的属性。窗口部件是用户界面的一个原子:它从窗口系统接收鼠窗口部件是用户界面的一个原子:它从窗口系统接收鼠标、键盘和其它事件,并且在屏幕上绘制自己的表现。标、键盘和其它事件,并且在屏幕上

38、绘制自己的表现。按钮(按钮(Button)、菜单()、菜单(menu)、滚动条()、滚动条(scrollbars)和框架()和框架(frame)都是窗口部件的例子。)都是窗口部件的例子。通常,应用程序都是一个控件,只是这个控件是由很多通常,应用程序都是一个控件,只是这个控件是由很多其它的控件组成其它的控件组成2021/8/2239QWidget类(续)类(续)窗口部件可以包含其它的窗口部件。例如,一个应用程窗口部件可以包含其它的窗口部件。例如,一个应用程序界面通常就是一个包含了序界面通常就是一个包含了QMenuBar,一些一些QToolBar,一个一个QStatusBar和其它的一些部件的窗口

39、。和其它的一些部件的窗口。绝大多数应用程序使用一个绝大多数应用程序使用一个QMainWindow或者一个或者一个QDialog作为程序界面,但是作为程序界面,但是Qt允许任何窗口部件成为窗允许任何窗口部件成为窗口。口。当窗口部件被创建的时候,它总是隐藏的,必须调用当窗口部件被创建的时候,它总是隐藏的,必须调用show()来使它可见。来使它可见。QWidget类有很多成员函数,但一般不直接使用,而是类有很多成员函数,但一般不直接使用,而是通过子类继承来使用其函数功能。如,通过子类继承来使用其函数功能。如,QPushButton、QlistBox等都是它的子类等都是它的子类2021/8/2240上

40、下文上下文 函数函数 窗口函数 show()、hide()、raise()、lower()、close()。 顶级窗口 caption()、setCaption()、icon()、setIcon()、iconText()、setIconText()、isActiveWindow()、setActiveWindow()、showMinimized()、showMaximized()、showFullScreen()、showNormal()。 窗口内容 update()、repaint()、erase()、scroll()、updateMask()。 几何形状 pos()、size()、rect

41、()、x()、y()、width()、height()、sizePolicy()、setSizePolicy()、sizeHint()、updateGeometry()、layout()、move()、resize()、setGeometry()、frameGeometry()、geometry()、childrenRect()、adjustSize()、mapFromGlobal()、mapFromParent()、mapToGlobal()、mapToParent()、maximumSize()、minimumSize()、sizeIncrement()、setMaximumSize()、

42、setMinimumSize()、setSizeIncrement()、setBaseSize()、setFixedSize()。 模式 isVisible()、isVisibleTo()、visibleRect()、isMinimized()、isDesktop()、isEnabled()、isEnabledTo()、isModal()、isPopup()、isTopLevel()、setEnabled()、hasMouseTracking()、setMouseTracking()、isUpdatesEnabled()、setUpdatesEnabled()。 观感 style()、setS

43、tyle()、cursor()、setCursor()、font()、setFont()、palette()、setPalette()、backgroundMode()、setBackgroundMode()、colorGroup()、fontMetrics()、fontInfo()。 键盘焦点函数 isFocusEnabled()、setFocusPolicy()、focusPolicy()、hasFocus()、setFocus()、clearFocus()、setTabOrder()、setFocusProxy()。 鼠标和键盘捕获 grabMouse()、releaseMouse()、

44、grabKeyboard()、releaseKeyboard()、mouseGrabber()、keyboardGrabber()。 事件处理器 event()、mousePressEvent()、mouseReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent()、keyPressEvent()、keyReleaseEvent()、focusInEvent()、focusOutEvent()、wheelEvent()、enterEvent()、leaveEvent()、paintEvent()、moveEvent()、resizeEvent

45、()、closeEvent()、dragEnterEvent()、dragMoveEvent()、dragLeaveEvent()、dropEvent()、childEvent()、showEvent()、hideEvent()、customEvent()。 变化处理器 enabledChange()、fontChange()、paletteChange()、styleChange()、windowActivationChange()。 系统函数 parentWidget()、topLevelWidget()、reparent()、polish()、winId()、find()、metric(

46、)。 这是什么的帮助 customWhatsThis()。 内部核心函数 focusNextPrevChild()、wmapper()、clearWFlags()、getWFlags()、setWFlags()、testWFlags()。 41Qt程序要素2021/8/2242初始化初始化QApplication在在Qt应用程序中,首先要创建一个应用程序中,首先要创建一个QApplication对象对象QApplication类负责图形用户界面应用程序的控制流和类负责图形用户界面应用程序的控制流和主要设置主要设置在在main.cpp中定义如下:中定义如下:intmain(intargc,cha

47、r*argv)QApplicationa(argc,argv);2021/8/2243初始化初始化QApplicationQApplication包含主事件循环体,对所有来自窗口系统包含主事件循环体,对所有来自窗口系统和其它资源的事件进行处理和调度,还包括处理应用程和其它资源的事件进行处理和调度,还包括处理应用程序的初始化和结束,并且提供会话管理,处理绝大多数序的初始化和结束,并且提供会话管理,处理绝大多数系统范围和应用程序范围的设置。系统范围和应用程序范围的设置。在在Qt应用程序中,不管有多少个窗口,应用程序中,不管有多少个窗口,QApplication对象只能有一个,而且必须在其他对象之前

48、创建,对象只能有一个,而且必须在其他对象之前创建,可以可以利用全局指针利用全局指针qApp访问访问QApplication对象对象。QApplication类中封装了很多函数,其中包括:类中封装了很多函数,其中包括:系统设置:系统设置:setFont()用来设置字体用来设置字体事件处理:事件处理:sendEvent()用来发送事件用来发送事件GUI风格:风格:setStyles()设置图形用户界面的风格设置图形用户界面的风格颜色使用:颜色使用:colorSpec()用来返回颜色文件用来返回颜色文件文本处理:文本处理:translate()用来处理文本信息用来处理文本信息创建组件:创建组件:se

49、tmainWidget()用来设置窗口的主组件用来设置窗口的主组件2021/8/2244退出退出QApplication退出应用程序可以调用继承自退出应用程序可以调用继承自QCoreApplication的的quit函数或函数或exit函数函数QApplication是是QCoreApplication类的子类类的子类quit():告诉应用程序退出,并返回:告诉应用程序退出,并返回0(表示成功)(表示成功)exit(0):同:同quit()举例举例QPushButton*quitButton=newQPushButton(Quit);connect(quitButton,SIGNAL(clic

50、ked(),qApp,SLOT(quit();或或qApp-exit(0);2021/8/2245退出退出QApplication调用调用QApplication:closeAllWindows()尤其适用于有多个顶层窗口的应用程序尤其适用于有多个顶层窗口的应用程序如果关闭窗口后,不想让应用程序退出,则需要调用函数如果关闭窗口后,不想让应用程序退出,则需要调用函数QApplication:setQuitOnLastWindowClosed(false)举例举例exitAct=newQAction(tr(E&xit),this);exitAct-setShortcuts(QKeySequence

51、:Quit);exitAct-setStatusTip(tr(Exittheapplication);connect(exitAct,SIGNAL(triggered(),qApp,SLOT(closeAllWindows();2021/8/2246创建窗口创建窗口在在Qt程序中,创建窗口比较简单,只要在程序中,创建窗口比较简单,只要在main.cpp文件中为文件中为ApplicationWindow建立一建立一个指针:个指针:ApplicationWindow*mw=newApplicatonWindow();ApplicationWindow是在是在Application.h中定义中定义的

52、类,它是一个的类,它是一个QMainWindow的子类的子类2021/8/2247创建组件创建组件组件的创建需要调用相应组件的类,并在头文件中包含此类的头文组件的创建需要调用相应组件的类,并在头文件中包含此类的头文件或者创建自定义类,继承组件类的功能件或者创建自定义类,继承组件类的功能#include“qpushbutton.h”classhello:publicQWidgethello类继承了类继承了QWidget类的特征,并加入了自定义的特征功能,类的特征,并加入了自定义的特征功能,同样需要在头文件中包含此类的头文件同样需要在头文件中包含此类的头文件在在main.cpp的函数中需要创建的函

53、数中需要创建hello类的实例,或创建类的实例,或创建QPushButton类的实例,才可以使用类的实例,才可以使用helloh(string);QPushButtonhello(“Hello,world!”,0);2021/8/2248创建组件(续)创建组件(续)如果组件本身可以作为主窗口,则无需设置主窗口。在上例中,按如果组件本身可以作为主窗口,则无需设置主窗口。在上例中,按钮创建时其构造函数中的第二个参数为钮创建时其构造函数中的第二个参数为0,表示按钮所在窗口为主,表示按钮所在窗口为主窗口,不需要设置主窗口。否则需要调用窗口,不需要设置主窗口。否则需要调用QWidget成员函数成员函数s

54、etMainWidget()来进行设置来进行设置h.setMainWidget(&h);组件创建时一般是不可见的,这样的好处在于避免大量组件创建时组件创建时一般是不可见的,这样的好处在于避免大量组件创建时造成的屏幕闪烁现象,要使组件可见需要调用造成的屏幕闪烁现象,要使组件可见需要调用QWidget类的成员函类的成员函数数show()来显示组件来显示组件h.show();2021/8/2249事件事件在在X程序中,敲击键盘,鼠标指针在窗口中的移程序中,敲击键盘,鼠标指针在窗口中的移动或鼠标按键动作等,都是事件动或鼠标按键动作等,都是事件在在Xt中提供了一种叫做回调的事件处理方式。中提供了一种叫做

55、回调的事件处理方式。通过翻译表,将事件映射为相应的动作,当组件得通过翻译表,将事件映射为相应的动作,当组件得到事件通知,就去表中找出相应的动作例程进行处到事件通知,就去表中找出相应的动作例程进行处理。理。这种机制需要应用程序注册有关组件的回调函数或这种机制需要应用程序注册有关组件的回调函数或普通的事件处理函数,以分发循环普通的事件处理函数,以分发循环Xt的事件的事件2021/8/2250事件(续)事件(续)Qt事件的处理过程事件的处理过程QApplication的事件循环体从事件队列中拾取本地窗口系统事件的事件循环体从事件队列中拾取本地窗口系统事件或其他事件或其他事件译成译成QEvent(),

56、并送给,并送给QObject:event(),最后送给,最后送给QWidget:event()分别对事件处理分别对事件处理QApplicationQWidget:event() QEventQObject:event()Y 等待事件 读取事件 检查事件类型 处理事件 退出事件处理循环事件处理循环部分N2021/8/2251Signal/Slot事件处理机制2021/8/2252回调函数回调函数回调函数是一个通过函数指针调用的函数。回调函数是一个通过函数指针调用的函数。如果把函数的指针如果把函数的指针(地址地址)作为参数传递给另一个作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数函数

57、,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。时,我们就说这是回调函数。回调函数不是由该函数的实现方式直接调用,回调函数不是由该函数的实现方式直接调用,而是在特定的事件或条件发生时由另外的一方而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。调用的,用于对该事件或条件进行响应。2021/8/2253Signal/Slot机制机制Qt程序中,事件处理的方式也是回调,但与回调函数所程序中,事件处理的方式也是回调,但与回调函数所不同的是,事件的发出和接收采用了信号(不同的是,事件的发出和接收采用了信号(signal)和)和插槽(插槽(slot)机制,无须调用

58、翻译表,是类型安全的回)机制,无须调用翻译表,是类型安全的回调。调。类似于观察者设计模式类似于观察者设计模式信号槽机制可以在对象之间彼此并不了解的情况下将它们的行信号槽机制可以在对象之间彼此并不了解的情况下将它们的行为联系起来。为联系起来。槽函数能和信号相连接,只要信号发出了,这个槽函数就会自槽函数能和信号相连接,只要信号发出了,这个槽函数就会自动被调用。动被调用。利用信号和插槽进行对象间的通信是利用信号和插槽进行对象间的通信是Qt的最主要特征之的最主要特征之一。一。2021/8/2254Signal/Slot机制(续)机制(续)当对象状态发生改变的时候,发出当对象状态发生改变的时候,发出si

59、gnal通知所有的通知所有的slot接收接收signal,尽管它并不知道哪些函数定义了,尽管它并不知道哪些函数定义了slot,而,而slot也同样不知道要接收怎样的也同样不知道要接收怎样的signalsignal和和slot机制真正实现了封装的概念,机制真正实现了封装的概念,slot除了接除了接收收signal之外和其它的成员函数没有什么不同之外和其它的成员函数没有什么不同signal和和slot之间是多对多的对应关系。之间是多对多的对应关系。在在QObject中实现中实现2021/8/2255Signal/Slot实例实例Qt程序的窗口部件发射信号(程序的窗口部件发射信号(signals)来

60、指出一个用)来指出一个用户的动作或者是状态的变化。户的动作或者是状态的变化。当信号被发射的时候,和信号相连的槽就会自动执行。当信号被发射的时候,和信号相连的槽就会自动执行。“信号和槽信号和槽”机制用于机制用于Qt对象间的通讯。对象间的通讯。#include #include int main (int argc, char *argv ) QApplication app (argc, argv); QPushButton *button = new QPushButton (“Qui”,0); QObject:connect (button, SIGNAL (clicked (), &app

61、, SLOT (quit (); button-show (); return app. exec ();2021/8/2256Signal和和Slot的声明的声明class Student : public QObject Q_OBJECTpublic: Student() myMark = 0; int mark() const return myMark; public slots: void setMark(int newMark);signals: void markChanged(int newMark);private: int myMark;在在Qt程序设计中,凡是包含程序设计

62、中,凡是包含signal和和slot的类中都要加上的类中都要加上Q_OBJECT的定义的定义信号是一个类的成员方法,该方法的实现是由信号是一个类的成员方法,该方法的实现是由meta-object自动实现的自动实现的对于开发者只需要在类中声明这个信号,并不需要实现。对于开发者只需要在类中声明这个信号,并不需要实现。下面的例子给出了如何在一个类中定义下面的例子给出了如何在一个类中定义signal和和slot:2021/8/2257Signal和和Slot的声明(续)的声明(续)void Student:setMark(int newMark) if (newMark!= myMark) myMar

63、k = newMark; emit markChanged(myMark); signal的发出一般在事件的处理函数中,利用的发出一般在事件的处理函数中,利用emit发出发出signal在下面的例子中在在事件处理结束后发出在下面的例子中在在事件处理结束后发出signal2021/8/2258Signal和和Slot的声明(续)的声明(续)槽(槽(slot)和普通的)和普通的c+成员函数很像。成员函数很像。槽是类的一个成员方法,当信号触发时该方法执行。槽是类的一个成员方法,当信号触发时该方法执行。可以是虚函数(可以是虚函数(virtual)、可被重载()、可被重载(overload)、可以是公)

64、、可以是公有的(有的(public)、保护的()、保护的(protective)或者私有的)或者私有的(private)。)。可以象任何可以象任何c+成员函数一样被直接调用,可以传递任何类型成员函数一样被直接调用,可以传递任何类型的参数,可以使用默认参数。的参数,可以使用默认参数。槽不同于信号,需要开发者自己去实现。槽不同于信号,需要开发者自己去实现。2021/8/2259什么是槽什么是槽?槽在各种槽段(槽在各种槽段(section)中定义。)中定义。槽可以返回值,但并不是通过联接。槽可以返回值,但并不是通过联接。任何数量的信号可以关联到一个槽。任何数量的信号可以关联到一个槽。它以一个普通的函

65、数实现。它以一个普通的函数实现。它可以作为普通函数被调用。它可以作为普通函数被调用。public slots: void aPublicSlot();protected slots: void aProtectedSlot();private slots: void aPrivateSlot();connect(src, SIGNAL(sig(), dest, SLOT(slt();2021/8/2260什么是信号什么是信号?信号在信号段(信号在信号段(section)中定义)中定义信号总是返回空信号总是返回空信号总是不必实现信号总是不必实现由由moc来提供实现来提供实现信号可以关联到任意数量

66、的槽上信号可以关联到任意数量的槽上通常产生一个直接调用通常产生一个直接调用,但是可以在线程之间作为事件来但是可以在线程之间作为事件来传递传递,甚至可以用在套接字之间甚至可以用在套接字之间(使用第三方类使用第三方类)槽能以任意次序被激发槽能以任意次序被激发信号使用信号使用emit关键字发射出去。关键字发射出去。signals: void aSignal();emit aSignal();2021/8/2261Signal和和Slot的连接的连接boolQObject:connect(sender,SIGNAL(valueChanged(int),receiver,SLOT(display(int

67、);为了能够接受到信号,信号和槽需要使用为了能够接受到信号,信号和槽需要使用connect()函数函数关联起来。关联起来。connect()函数是函数是QObject类的成员函数,它能够连接类的成员函数,它能够连接signal和和slot,也可以用来连接也可以用来连接signal和和signal函数原形如下:函数原形如下:sender和和receiver是是QObject对象指针。对象指针。SIGNALE()和和SLOT()宏的作用是把他们的参数转换成字宏的作用是把他们的参数转换成字符串。符串。2021/8/2262Signal和和Slot的连接的连接boolQObject:connect(s

68、ender,SIGNAL(valueChanged(int),receiver,SLOT(display(int);为了能够接受到信号,信号和槽需要使用为了能够接受到信号,信号和槽需要使用connect()函数函数关联起来。关联起来。connect()函数是函数是QObject类的成员函数,它能够连接类的成员函数,它能够连接signal和和slot,也可以用来连接也可以用来连接signal和和signal函数原形如下:函数原形如下:sender和和receiver是是QObject对象指针。对象指针。SIGNALE()和和SLOT()宏的作用是把他们的参数转换成字宏的作用是把他们的参数转换成字

69、符串。符串。2021/8/2263Signal和和Slot的连接(续)的连接(续)连接规则连接规则一个信号可以连接到多个槽一个信号可以连接到多个槽多个信号可以连接到同一个槽多个信号可以连接到同一个槽一个信号可以和另一个信号相连一个信号可以和另一个信号相连连接可以被删除连接可以被删除boolQObject:disconnect(sender,SIGNAL(valueChanged(int),receiver,SLOT(display(int)这个函数很少使用,因为当一个对象被删除后,这个函数很少使用,因为当一个对象被删除后,Qt自动删除这个对象的所有连接自动删除这个对象的所有连接2021/8/2

70、264Signal和和Slot的连接(续)的连接(续)connect()函数举例:函数举例:QLabel *label = new QLabel; QScrollBar *scroll = new QScrollBar;QObject:connect( scroll, SIGNAL(valueChanged(int), label, SLOT(setNum(int) );2021/8/2265Signal和和Slot的连接(续)的连接(续)2021/8/2266同一个信号连接多个插槽同一个信号连接多个插槽connect(slider, SIGNAL(valueChanged(int), spi

71、nBox, SLOT(setValue(int);connect(slider, SIGNAL(valueChanged(int), this, SLOT(updateStatusBarIndicator(int);多个信号连接到同一个插槽多个信号连接到同一个插槽connect(lcd, SIGNAL(overflow(), this, SLOT(handleMathError();connect(calculator, SIGNAL(divisionByZero(), this, SLOT(handleMathError();Signal和和Slot的连接(续)的连接(续)2021/8/22

72、67一个信号连接到另一个信号一个信号连接到另一个信号connect(lineEdit, SIGNAL(textChanged(const QString &), this, SIGNAL(updateRecord(const QString &);取消一个连接取消一个连接disconnect(lcd,SIGNAL(overflow(), this, SLOT(handleMathError();取消一个连接不是很常用,因为取消一个连接不是很常用,因为Qt会在一个对象会在一个对象被删除后自动取消这个对象所包含的所有的连接被删除后自动取消这个对象所包含的所有的连接Signal和和Slot的连接(续

73、)的连接(续)2021/8/2268信号与槽机制深入信号与槽机制深入信号发生后信号发生后如果信号和槽实现在同一个线程中,当信号产生的时如果信号和槽实现在同一个线程中,当信号产生的时候,与它关联的槽就会马上得到执行候,与它关联的槽就会马上得到执行如果信号和槽不在同一个线程中,槽的执行可能会有如果信号和槽不在同一个线程中,槽的执行可能会有延迟延迟(nexteventloop)相关联的信号和槽必须满足一定条件相关联的信号和槽必须满足一定条件信号的参数可以多于槽的参数信号的参数可以多于槽的参数,多余的参数被忽略,反多余的参数被忽略,反之则不行之则不行信号和槽函数必须有着相同的参数类型及顺序信号和槽函数

74、必须有着相同的参数类型及顺序不会有编译时的错误检查不会有编译时的错误检查,运行时检查运行时检查如果参速类型不匹配,或者信号和槽不存在,应用程序在如果参速类型不匹配,或者信号和槽不存在,应用程序在debug状态下时,状态下时,Qt会在运行期间给出警告。会在运行期间给出警告。如果信号和槽连接时包含了参数的名字,如果信号和槽连接时包含了参数的名字,Qt也将会给出警告。也将会给出警告。2021/8/2269信号与槽机制深入(续)信号与槽机制深入(续)signal和和slot只是只是对于回调函数一个比较安全的封装对于回调函数一个比较安全的封装(wrapper)slot对应回调函数,对应回调函数,sign

75、al则相当于触发回调函数的方法。则相当于触发回调函数的方法。但但QApplication可以模拟异步的方式。可以模拟异步的方式。如果程序只是简单使用如果程序只是简单使用Qt的基本类,或者从的基本类,或者从QtObject派生派生而来的自定义类,而不是而来的自定义类,而不是QApplication的话,肯定不是异的话,肯定不是异步机制步机制实验:在实验:在emit之后之后printf(“emitn”);在在slot中中printf(“slotn”),结果,结果是首先打印是首先打印slot然后然后emit,这就表明了,这就表明了emit调用陷入了调用陷入了slot中。中。qApp在事件循环处理中截

76、取所有在事件循环处理中截取所有emit的的signal,然后调用相应的,然后调用相应的slots,就像回调函数一样,就像回调函数一样2021/8/2270建立关联建立关联QObject:connect( src, SIGNAL( signature ), dest, SLOT( signature ) ); ( . )clicked()toggled(bool)setText(QString)textChanged(QString)rangeChanged(int,int)setTitle(QString text)setValue(42)签名由函数名和参数类型组成。不允许有变量名或签名由函数

77、名和参数类型组成。不允许有变量名或值。值。自定义类型降低了可重用性自定义类型降低了可重用性QObject*setItem(ItemClass)2021/8/2271建立关联建立关联Qt参数可以忽略,但不能无中生有。参数可以忽略,但不能无中生有。SignalsrangeChanged(int,int)rangeChanged(int,int)rangeChanged(int,int)valueChanged(int)valueChanged(int)valueChanged(int)textChanged(QString)clicked()clicked()SlotssetRange(int,i

78、nt)setValue(int)updateDialog()setRange(int,int)setValue(int)updateDialog()setValue(int)setValue(int)updateDialog()2021/8/2272自动关联自动关联使用使用Designer,它很便捷地在接口和用户代码之间提供,它很便捷地在接口和用户代码之间提供自动关联。自动关联。通过调用通过调用QMetaObject:connectSlotsByName触发触发当命名时考虑重用性当命名时考虑重用性比较比较on_widget_signal和和updatePageMarginson_ object

79、 name _ signal name ( signal parameters )on_addButton_clicked();on_deleteButton_clicked();on_listWidget_currentItemChanged(QListWidgetItem*,QListWidgetItem*)updatePageMargins可以关联到一定数量信号或直接调用。2021/8/2273值同步值同步双向连接双向连接无限循环必须停止无限循环必须停止没有信号被发射,除非没有信号被发射,除非发生实际的变化。发生实际的变化。connect(dial1, SIGNAL(valueChang

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

81、IFY 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构造自然槽。信号匹配setter2021/8/2275setter实现细节实现细节void AngleObject:setAngle(qreal angle) if(m_angle = angle

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

83、个每一个包含包含一个一个QDial部件部件一个一个QLCDNumber部件部件2021/8/2278温度转换器温度转换器class TempConverter : public QObject Q_OBJECT public: TempConverter(int tempCelsius, QObject *parent = 0); int tempCelsius() const; int tempFahrenheit() const;public slots: void setTempCelsius(int); void setTempFahrenheit(int);signals: void

84、 tempCelsiusChanged(int); void tempFahrenheitChanged(int);private: int m_tempCelsius;先是Q_OBJECT 宏QObject 作为父对象父对象指针读和写函数当温度变化时发射信号。在内部表示整数摄氏度。2021/8/2279温度转换器温度转换器void TempConverter:setTempCelsius(int tempCelsius) if(m_tempCelsius = tempCelsius) return; m_tempCelsius = tempCelsius; emit tempCelsiusC

85、hanged(m_tempCelsius); emit tempFahrenheitChanged(tempFahrenheit();void TempConverter:setTempFahrenheit(int tempFahrenheit) int tempCelsius = (5.0/9.0)*(tempFahrenheit-32); setTempCelsius(tempCelsius);setTempCelsius槽槽:setTempFahrenheit槽槽:测试改变以中断递归更新对象的状态发射信号反映改变转换,传递摄氏度是内部表现形式。2021/8/2280温度转换器温度转换器表

86、盘通过表盘通过TempConverter联系起来联系起来LCD显示直接受表盘来驱动。显示直接受表盘来驱动。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(va

87、lueChanged(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(setTempFa

88、hrenheit(int);connect(fahrenheitDial, SIGNAL(valueChanged(int), fahrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);2021/8/2281温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFah

89、renheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged(int), tempConverter, SLOT(setTempCelsius(int);connect(celsiusDial, SIGNAL(valueChanged(int), celsiusLcd, SLOT(d

90、isplay(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, SI

91、GNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);2021/8/2282温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged se

92、tValuevalueChanged displayconnect(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,

93、 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);2021/8/2283温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConverter

94、setTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged(int), tempConverter, SLOT(setTempCelsius(int);connect(c

95、elsiusDial, 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), fa

96、hrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);2021/8/2284温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahre

97、nheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged(int), tempConverter, SLOT(setTempCelsius(int);connect(celsiusDial, SIGNAL(valueChanged(int), celsiusLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempCelsiusChanged(int),

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

99、);2021/8/2285温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalueChanged displayconnect(celsiusDial, SIGNAL(valueChanged

100、(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(i

101、nt);connect(fahrenheitDial, SIGNAL(valueChanged(int), fahrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);2021/8/2286温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitCha

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

103、);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(tempF

104、ahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);2021/8/2287温度转换器温度转换器用户调节摄氏度表盘。用户调节摄氏度表盘。TempConvertersetTempCelsiussetTempFahrenheittempCelsiusChangedtempFahrenheitChangedvalueChanged setTempCelsiusvalueChanged setTempFahrenheittempCelsiusChanged setValuetempFahrenheitChanged setValuevalu

105、eChanged displayconnect(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(va

106、lueChanged(int), tempConverter, SLOT(setTempFahrenheit(int);connect(fahrenheitDial, SIGNAL(valueChanged(int), fahrenheitLcd, SLOT(display(int);connect(tempConverter, SIGNAL(tempFahrenheitChanged(int), fahrenheitDial, SLOT(setValue(int);2021/8/2288与值关联与值关联?一种常见情况是,希望在关联声明中一种常见情况是,希望在关联声明中传递一个值。传递一个值。

107、例如例如,键盘实例键盘实例这不是有效的这不是有效的-它将不会关联。它将不会关联。connect(key, SIGNAL(clicked(), this, SLOT(keyPressed(1);2021/8/2289与值关联与值关联?解决方法解决方法#1:多个槽多个槽 .public slots: void key1Pressed(); void key2Pressed(); void key3Pressed(); void key4Pressed(); void key5Pressed(); void key6Pressed(); void key7Pressed(); void key8Pr

108、essed(); void key9Pressed(); void key0Pressed(); .connections2021/8/2290与值关联与值关联?解决方法解决方法#2:子类发射器和增加信号子类发射器和增加信号QPushButtonQIntPushButton .signals: void clicked(int); . QIntPushButton *b; b=new QIntPushButton(1); connect(b, SIGNAL(clicked(int), this, SLOT(keyPressed(int); b=new QIntPushButton(2); co

109、nnect(b, SIGNAL(clicked(int), this, SLOT(keyPressed(int); b=new QIntPushButton(3); connect(b, SIGNAL(clicked(int), this, SLOT(keyPressed(int); .2021/8/2291解决方案评价解决方案评价#1:多个槽多个槽许多槽包含几乎相同的代码许多槽包含几乎相同的代码难于维护难于维护(一个小的变化影响所有槽一个小的变化影响所有槽)难于扩展难于扩展(每次都要新建槽每次都要新建槽)#2:子类发射器和增加信号子类发射器和增加信号额外的专用类额外的专用类(难于重用难于重用

110、)难于扩展难于扩展(每个情况需新建子类每个情况需新建子类)2021/8/2292信号映射器信号映射器QSignalMapper类解决了这个问题类解决了这个问题将每个值映射到每个发射器将每个值映射到每个发射器介于可重用类之间介于可重用类之间 QSignalMapper *m = QSignalMapper(this); QPushButton *b; b=new QPushButton(1); connect(b, SIGNAL(clicked(), m, SLOT(map(); m-setMapping(b, 1); . connect(m, SIGNAL(mapped(int), this, SLOT(keyPressed(int);创建一个信号映射器关联按钮到映射器关联一个发射器和一个值。关联映射器到槽上。2021/8/2293信号映射器信号映射器QSignalMapper .public slots: void keyPressed(); .connectionsconnection信号映射器把每一个按钮和值关联起来。信号映射器把每一个按钮和值关联起来。这些值都被映射。这些值都被映射。当一个值被映射,映射器发出携带关联的当一个值被映射,映射器发出携带关联的值的映射信号(值的映射信号(int)。)。2021/8/2294

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号