收藏 分享(赏)

Qt入门教程详细讲解版.pdf

上传人:weiwoduzun 文档编号:4015727 上传时间:2018-12-05 格式:PDF 页数:91 大小:872.11KB
下载 相关 举报
Qt入门教程详细讲解版.pdf_第1页
第1页 / 共91页
Qt入门教程详细讲解版.pdf_第2页
第2页 / 共91页
Qt入门教程详细讲解版.pdf_第3页
第3页 / 共91页
Qt入门教程详细讲解版.pdf_第4页
第4页 / 共91页
Qt入门教程详细讲解版.pdf_第5页
第5页 / 共91页
点击查看更多>>
资源描述

1、如何学习 Qt 我们假设你已经熟悉 C+了!请先阅读一下 Qt 白皮书 。 它包含一个关于 Qt 软件的概述, 并且提供了一些用来示范使用 Qt 进行编程的代码的片断。它会给你一个“大的图画”。如果你想要完全的在 C+中进行编程, 不使用任何设计工具的帮助下在代码中设计你的界面,请阅读教程。 教程 1 就是被设计成把你带入 Qt 编程的一个教程,它更强调的是编写代码而不是一个特征的漫游。 教程 2 是一个更加真实的例子,示范了如何编写菜单、工具条、文件的载入和保存、对话框等地那个。如果你想使用一个设计工具来设计你的用户界面,那么你至少要先阅读 Qt 设计器手册 的前几章。 在这之后, 学习一下

2、上面提到的纯粹的 C+教程 ( 教程 1 和 教程 2)还是很值得的。到现在为止,如果你已经完成了一些小的可以工作的应用程序并且对 Qt 编程有了一个主要的了解。 你可以直接开始你自己的项目了, 但我们建议你阅读一些关键的概述来加深你对 Qt 的理解: 对象模型 和 信号和槽 。在这里我们建议你看一下 概述 并且阅读一些和你的项目相关的文章。 你也许会发现浏览和你项目做相同事情的 实例 的源代码是非常有用的。你也可以阅读 Qt 的源代码,因为它们也被提供。如果你运行 demo这个应用程序(在 $QTDIR/examples/demo),你就会看到很多运转中的 Qt 窗口部件Qt 提供了广泛的文

3、档,完全前后参考的超文本,所以你可以很容易地按你喜欢的方式进行点击。在文档中,你最经常使用的部分可能就是 API 参考 。每一个链接都提供了一个不同的方式来导航 API 参考,全都试试,看哪一个更适合你。你现在应该已经准备好你的伟大工程:祝你好运,玩得开心!Qt 教程一 共十四步这个教程介绍了使用 Qt 工具包进行图形用户界面编程。 它没有包括所有的东西:强调的是教授一种图形用户界面编程的编程思想,并且介绍 Qt 的特征也是必需的。一些通常情况下使用的特征在这个教程里没有用到。第一章开始讲述一个十行的 Hello World 程序并且后来的每一章都介绍了一个或几个更多的概念。 一直到第十四章,

4、 程序已经从第一章的十行变成了六百五十行的游戏。如果你对 Qt 完全不熟悉,如果你还没有读过 如何学习 Qt 的话,请读一下。教程章节:1. Hello, World!2. 调用退出3. 家庭价值4. 使用窗口部件5. 组装积木6. 组装丰富的积木!7. 一个事物领导另一个8. 准备战斗9. 你可以使用加农炮了10. 像丝一样滑11. 给它一个炮弹12. 悬在空中的砖13. 游戏结束14. 面对墙壁这个小游戏看起来不像一个现代的图形用户界面应用程序。 它只使用了有用的少数图形用户界面技术, 但是如果你通过它工作之后, 我们建议你阅读一下 教程二 。第二个教程更加正式一些, 并且覆盖了包括菜单条

5、、 工具条、 文件的载入和保存、对话框等典型应用程序的特征。Qt 教程一 第一章: Hello, World! 第一个程序是一个简单的 Hello World 例子。 它只包含你建立和运行 Qt 应用程序所需要的最少的代码。上面的图片是这个程序的快照。/* * * Qt 教程一 - 2 * */ #include #include int main( int argc, char *argv ) QApplication a( argc, argv ); QPushButton hello( “Hello world!“, 0 ); hello. resize ( 100, 30 ); a.

6、setMainWidget ( hello. show(); return a. exec(); 一行一行地解说#include 这一行包含了 QApplication 类的定义。在每一个使用 Qt 的应用程序中都必须使用一个 QApplication 对象。 QApplication 管理了各种各样的应用程序的广泛资源,比如默认的字体和光标。#include 这一行包含了 QPushButton 类的定义。 参考文档 的文件的最上部分提到了使用哪个类就必须包含哪个头文件的说明。QPushButton 是一个经典的图形用户界面按钮,用户可以按下去,也可以放开。它管理自己的观感, 就像其它每一个

7、 QWidget。 一个窗口部件就是一个可以处理用户输入和绘制图形的用户界面对象。 程序员可以改变它的全部 观感 和它的许多主要的属性(比如颜色),还有这个窗口部件的内容。一个 QPushButton 可以显示一段文本或者一个 QPixmap。int main( int argc, char *argv ) main()函数是程序的入口。几乎在使用 Qt 的所有情况下, main()只需要在把控制转交给 Qt 库之前执行一些初始化, 然后 Qt库通过事件来向程序告知用户的行为。argc 是命令行变量的数量, argv 是命令行变量的数组。这是一个 C/C+特征。它不是 Qt 专有的,无论如何

8、Qt 需要处理这些变量(请看下面)。QApplication a( argc, argv ); a 是这个程序的 QApplication 。它在这里被创建并且处理这些命令行变量(比如在 X 窗口下的 -display) 。 请注意, 所有被 Qt 识别的命令行参数都会从 argv 中被移除(并且 argc 也因此而减少)。关于细节请看 QApplication:argv ()文档。注意: 在任何 Qt 的窗口系统部件被使用之前创建 QApplication 对象是必须的。QPushButton hello( “Hello world!“, 0 ); 这里, 在 QApplication 之后

9、 , 接着的是第一个窗口系统代码: 一个按钮被创建了。这个按钮被设置成显示“ Hello world! ”并且它自己构成了一个窗口(因为在构造函数指定 0 为它的父窗口,在这个父窗口中按钮被定位)。hello. resize ( 100, 30 ); 这个按酒被设置成 100 像素宽, 30 像素高(加上窗口系统边框)。在这种情况下,我们不用考虑按钮的位置,并且我们接受默认值。a. setMainWidget ( 这个按钮被选为这个应用程序的主窗口部件。 如果用户关闭了主窗口部件, 应用程序就退出了。你不用必须设置一个主窗口部件,但绝大多数程序都有一个。hello. show(); 当你创建一

10、个窗口部件的时候, 它是不可见的。 你必须调用 show()来使它变为可见的。return a. exec(); 这里就是 main()把控制转交给 Qt,并且当应用程序退出的时候 exec()就会返回。在 exec()中, Qt 接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。 你现在可以试着编译和运行这个程序了。编译编译一个 C+应用程序,你需要创建一个 makefile。创建一个 Qt 的 makefile 的最容易的方法是使用 Qt 提供的连编工具 qmake。如果你已经把 main.cpp 保存到它自己的目录了,你所要做的就是这些:qmake -project qmake

11、第一个命令调用 qmake来生成一个 .pro (项目)文件。第二个命令根据这个项目文件来生成一个(系统相关的) makefile。你现在可以输入 make(或者 nmake,如果你使用 Visual Studio),然后运行你的第一个 Qt 应用程序!行为当你运行它的时候, 你就会看到一个被单一按钮充满的小窗口, 在它上面你可以读到著名的词: Hellow World! 练习试着改变窗口的大小。按下按钮。如果你在 X 窗口下运行,使用 -geometry 选项(比如, -geometry 100x200+10+20 )来运行这个程序。现在你可以进行 第二章 了。下一章 教程一主页 Qt 教程

12、一 第二章:调用退出你已经在 第一章 中创建了一个窗口, 我们现在使这个应用程序在用户让它退出的时候退出。我们也会使用一个比默认字体更好的一个字体。/* * * Qt 教程一 - 2 * */ #include #include #include int main( int argc, char *argv ) QApplication a( argc, argv ); QPushButton quit( “Quit“, 0 ); quit. resize ( 75, 30 ); quit. setFont ( QFont( “Times“, 18, QFont:Bold ) ); QObje

13、ct: connect ( a. setMainWidget ( quit. show(); return a. exec(); 一行一行地解说#include 因为这个程序使用了 QFont,所以它需要包含 qfont.h。 Qt 的字体提取和 X 中提供的可怕的字体提取大为不同,字体的载入和使用都已经被高度优化了。QPushButton quit( “Quit“, 0 ); 这时, 按钮显示 “ Quit” , 确切的说这就是当用户点击这个按钮时程序所要做的。这不是一个巧合。 因为这个按钮是一个顶层窗口, 我们还是把 0 作为它的父对象。quit. resize ( 75, 30 ); 我

14、们给这个按钮选择了另外一个大小,因为这个文本比“ Hello world! ”小一些。我们也可以使用 QFontMetrics 来设置正确的大小。quit. setFont ( QFont( “Times“, 18, QFont:Bold ) ); 这里我们给这个按钮选择了一个新字体, Times 字体中的 18 点加粗字体。注意在这里我们调用了这个字体。你也可以改变整个应用程序的默认字体(使用 QApplication:setFont())。QObject: connect ( connect也许是 Qt 中 最重要 的特征了。 注意 connect()是 QObject 中的一个静态函数。

15、不要把这个函数和 socket库中的 connect()搞混了。这一行在两个 Qt 对象(直接或间接继承 QObject 对象的对象)中建立了一种单向的连接。每一个 Qt 对象都有 signals (发送消息)和 slots (接收消息)。所有窗口部件都是 Qt 对象。它们继承 QWidget,而 QWidget 继承 QObject。这里 quit 的 clicked()信号和 a 的 quit()槽连接起来了,所以当这个按钮被按下的时候,这个程序就退出了。信号和槽 文档详细描述了这一主题。行为当你运行这个程序的时候, 你会看到这个窗口比第一章中的那个小一些, 并且被一个更小的按钮充满。(请

16、看 编译 来学习如何创建一个 makefile 和连编应用程序。)练习试着改变窗口的大小。按下按钮。注意! connect()看起来会有一些不同。是不是在 QPushButton中还有其它的你可以连接到 quit 的信号?提示:QPushButton继承了 QButton 的绝大多数行为。现在你可以进行 第三章 了。Qt 教程一 第三章:家庭价值这个例子演示了如何创建一个父窗口部件和子窗口部件。我们将会保持这个程序的简单性, 并且只使用一个单一的父窗口部件和一个独立的子窗口部件。/* * * Qt 教程一 - 3 * */ #include #include #include #include

17、 int main( int argc, char *argv ) QApplication a( argc, argv ); QVBox box; box. resize ( 200, 120 ); QPushButton quit( “Quit“, quit. setFont ( QFont( “Times“, 18, QFont:Bold ) ); QObject: connect ( a. setMainWidget ( box. show(); return a. exec(); 一行一行地解说#include 我们添加了一个头文件 qvbox.h 用来获得我们要使用的布局类。QVB

18、ox box; 这里我们简单地创建了一个垂直的盒子容器。 QVBox 把它的子窗口部件排成一个垂直的行, 一个在其它的上面, 根据每一个子窗口部件的 QWidget:sizePolicy()来安排空间。box. resize ( 200, 120 ); 我们它的高设置为 120 像素,宽为 200 像素。QPushButton quit( “Quit“, 子窗口部件产生了。QPushButton通过一个文本(“ text”)和一个父窗口部件( box)生成的。子窗口部件总是放在它的父窗口部件的最顶端。 当它被显示的时候, 它被父窗口部件的边界挡住了一部分。父窗口部件, QVBox ,自动地把这

19、个子窗口部件添加到它的盒子中央。因为没有其它的东西被添加了,这个按钮就获得了父窗口部件的所有空间。box. show(); 当父窗口部件被显示的时候, 它会调用所有子窗口部件的显示函数 (除非在这些子窗口部件中你已经明确地使用 QWidget:hide())。行为这个按钮不再充满整个窗口部件。相反,它获得了一个“自然的”大小。这是因为现在的这个新的顶层窗口, 使用了按钮的大小提示和大小变化策略来设置这个按钮的大小和位置。 (请看 QWidget:sizeHint()和 QWidget:setSizePolicy()来获得关于这几个函数的更详细的信息。)(请看 编译 来学习如何创建一个 make

20、file 和连编应用程序。)练习试着改变窗口的大小。 按钮是如何变化的?按钮的大小变化策略是什么?如果你运行这个程序的时候使用了一个大一些的字体, 按钮的高度发生了什么变化?如果你试图让这个窗口 真的 变小,发生了什么?现在你可以进行 第四章 了。Qt 教程一 第四章:使用窗口部件这个例子显示了如何创建一个你自己的窗口部件, 描述如何控制一个窗口部件的最小大小和最大大小,并且介绍了窗口部件的名称。/* * * Qt 教程一 - 4 * */ #include #include #include class MyWidget : public QWidget public: MyWidget(

21、QWidget *parent=0, const char *name=0 ); ; MyWidget:MyWidget( QWidget *parent, const char *name ) : QWidget( parent, name ) setMinimumSize ( 200, 120 ); setMaximumSize( 200, 120 ); QPushButton *quit = new QPushButton( “Quit“, this, “quit“ ); quit- setGeometry ( 62, 40, 75, 30 ); quit- setFont ( QFon

22、t( “Times“, 18, QFont:Bold ) ); connect ( quit, SIGNAL( clicked (), qApp, SLOT( quit () ); int main( int argc, char *argv ) QApplication a( argc, argv ); MyWidget w; w. setGeometry ( 100, 100, 200, 120 ); a. setMainWidget ( w. show(); return a. exec(); 一行一行地解说class MyWidget : public QWidget public:

23、MyWidget( QWidget *parent=0, const char *name=0 ); ; 这里我们创建了一个新类。 因为这个类继承了 QWidget, 所以新类是一个窗口部件,并且可以最为一个顶层窗口或者子窗口部件(像第三章里面的按钮)。这个类只有一个成员函数,构造函数(加上从 QWidget 继承来的成员函数)。这个构造函数是一个标准的 Qt 窗口部件构造函数,当你创建窗口部件时,你应该总是包含一个相似的构造函数。第一个参数是它的父窗口部件。 为了生成一个顶层窗口, 你指定一个空指针作为父窗口部件。就像你看到的那样,这个窗口部件默认地被认做是一个顶层窗口。第二个参数是这个窗口

24、部件的名称。 这个 不是 显示在窗口标题栏或者按钮上的文本。 这只是分配给窗口部件的一个名称, 以后可以用来 查找 这个窗口部件, 并且这里还有一个 方便的调试功能 可以完整地列出窗口部件层次。MyWidget:MyWidget( QWidget *parent, const char *name ) : QWidget( parent, name ) 构造函数的实现从这里开始。 像大多数窗口部件一样, 它把 parent 和 name传递给了 QWidget 的构造函数。 setMinimumSize ( 200, 120 ); setMaximumSize( 200, 120 ); 因为这

25、个窗口部件不知道如何处理重新定义大小, 我们把它的最小大小和最大大小设置为相等的值, 这样我们就确定了它的大小。 在下一章, 我们将演示窗口部件如何响应用户的重新定义大小事件。QPushButton *quit = new QPushButton( “Quit“, this, “quit“ ); quit- setGeometry ( 62, 40, 75, 30 ); quit- setFont ( QFont( “Times“, 18, QFont:Bold ) ); 这里我们创建并设置了这个窗口部件的一个名称为“ quit”的子窗口部件(新窗口部件的父窗口部件是 this )。这个窗口部

26、件名称和按钮文本没有关系,只是在这一情况下碰巧相似。注意 quit 是这个构造函数中的局部变量。 MyWidget 不能跟踪它,但 Qt 可以,当 MyWidget 被删除的时候,默认地它也会被删除。这就是为什么 MyWidget 不需要一个析构函数的原因。 (另外一方面,如果你选择删除一个子窗口部件,也没什么坏处,这个子窗口部件会自动告诉 Qt 它即将死亡。)setGeometry()调用和上一章的 move()和 resize()是一样的。connect ( quit, SIGNAL( clicked (), qApp, SLOT( quit () ); 因为 MyWidget 类不知道这

27、个应用程序对象,它不得不连接到 Qt 的指针, qApp。一个窗口部件就是一个软件组件并且它应该尽量少地知道关于它的环境, 因为它应该尽可能的通用和可重用。知道了应用程序的名称将会打破上述原则,所以在一个组件,比如 MyWidget ,需要和应用程序对象对话的这种情况下, Qt 提供了一个别名, qApp。int main( int argc, char *argv ) QApplication a( argc, argv ); MyWidget w; w. setGeometry ( 100, 100, 200, 120 ); a. setMainWidget ( w. show(); re

28、turn a. exec(); 这里我们举例说明了我们的新子窗口部件, 把它设置为主窗口部件, 并且执行这个应用程序。行为这个程序和上一章的在行为上非常相似。 不同点是我们实现的方式。 无论如何它的行为还是有一些小差别。试试改变它的大小,你会看到什么?(请看 编译 来学习如何创建一个 makefile 和连编应用程序。)练习试着在 main()中创建另一个 MyWidget 对象。发生了什么?试着添加更多的按钮或者把除了 QPushButton之外的东西放到窗口部件中。现在你可以进行 第五章 了。| 注释的类 | 分组的类 | 函数Qt 教程一 第五章:组装积木这个例子显示了创建几个窗口部件并

29、用信号和槽把它们连接起来, 和如何处理重新定义大小事件。/* * * Qt 教程一 - 5 * */ #include #include #include #include #include #include class MyWidget : public QVBox public: MyWidget( QWidget *parent=0, const char *name=0 ); ; MyWidget:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) QPushButton *quit = new Q

30、PushButton( “Quit“, this, “quit“ ); quit- setFont ( QFont( “Times“, 18, QFont:Bold ) ); connect ( quit, SIGNAL( clicked (), qApp, SLOT( quit () ); QLCDNumber *lcd = new QLCDNumber( 2, this, “lcd“ ); QSlider * slider = new QSlider ( Horizontal, this, “slider“ ); slider- setRange( 0, 99 ); slider- set

31、Value ( 0 ); connect ( slider, SIGNAL( valueChanged(int), lcd, SLOT( display (int) ); int main( int argc, char *argv ) QApplication a( argc, argv ); MyWidget w; a. setMainWidget ( w. show(); return a. exec(); 一行一行地解说#include #include #include #include #include #include 这里显示的是三个新的被包含的头文件。 qslider.h 和

32、 qlcdnumber.h在这里是因为我们使用了两个新的窗口部件, QSlider 和 QLCDNumber。 qvbox.h 在这里是因为我们使用了 Qt 的自动布局支持。class MyWidget : public QVBox public: MyWidget( QWidget *parent=0, const char *name=0 ); ; MyWidget:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) MyWidget 现在继承了 QVBox ,而不是 QWidget。我们通过这种方式来

33、使用QVBox 的布局(它可以把它的子窗口部件垂直地放在自己里面)。重新定义大小自动地被 QVBox 处理,因此现在也就被 MyWidget 处理了。QLCDNumber *lcd = new QLCDNumber( 2, this, “lcd“ ); lcd 是一个 QLCDNumber,一个可以按像 LCD 的方式显示数字的窗口部件。这个实例被设置为显示两个数字,并且是 this 的子窗口部件。它被命名为“ lcd”。QSlider * slider = new QSlider ( Horizontal, this, “slider“ ); slider- setRange( 0, 99

34、); slider- setValue ( 0 ); QSlider 是一个经典的滑块,用户可以通过在拖动一个东西在一定范围内调节一个整数数值的方式来使用这个窗口部件。 这里我们创建了一个水平的滑块, 设置它的范围是 099(包括 0 和 99,参见 QSlider:setRange()文档)并且它的初始值是 0。connect ( slider, SIGNAL( valueChanged(int), lcd, SLOT( display (int) ); 这里我们是用了 信号 /槽机制 把滑块的 valueChanged()信号和 LCD 数字的 display()槽连接起来了。无论什么时候

35、滑块的值发生了变化,它都会通过发射 valueChanged()信号来广播这个新的值。因为这个信号已经和 LCD 数字的 display()槽连接起来了,当信号被广播的时候, 这个槽就被调用了。 这两个对象中的任何一个都不知道对方。 这就是组件编程的本质。槽是和普通 C+成员函数的方式不同,但有着普通 C+成员函数的方位规则。行为LCD 数字反应了你对滑块做的一切,并且这个窗口部件很好地处理了重新定义大小事件。注意当窗口被重新定义大小(因为它可以)的时候, LDC 数字窗口部件也改变了大小, 但是其它的还是和原来一样 (因为如果它们变化了, 看起来好像很傻)。(请看 编译 来学习如何创建一个

36、makefile 和连编应用程序。)练习试着改变 LCD 数字,添加更多的数字或者 改变模式 。你甚至可以添加四个按钮来设置基数。你也可以改变滑块的范围。也许使用 QSpinBox 比滑块更好?试着当 LCD 数字溢出的时候使这个应用程序退出。现在你可以进行 第六章 了。Qt 教程一 第六章:组装丰富的积木!这个例子显示了如何把两个窗口部件封装成一个新的组件和使用许多窗口部件是多么的容易。首先,我们使用一个自定义的窗口部件作为一个子窗口部件。/* * * Qt 教程一 - 6 * */ #include #include #include #include #include #include

37、#include class LCDRange : public QVBox public: LCDRange( QWidget *parent=0, const char *name=0 ); ; LCDRange:LCDRange( QWidget *parent, const char *name ) : QVBox( parent, name ) QLCDNumber *lcd = new QLCDNumber( 2, this, “lcd“ ); QSlider * slider = new QSlider ( Horizontal, this, “slider“ ); slider

38、- setRange( 0, 99 ); slider- setValue ( 0 ); connect ( slider, SIGNAL( valueChanged(int), lcd, SLOT( display (int) ); class MyWidget : public QVBox public: MyWidget( QWidget *parent=0, const char *name=0 ); ; MyWidget:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) QPushButton

39、*quit = new QPushButton( “Quit“, this, “quit“ ); quit- setFont ( QFont( “Times“, 18, QFont:Bold ) ); connect ( quit, SIGNAL( clicked (), qApp, SLOT( quit () ); QGrid *grid = new QGrid( 4, this ); for( int r = 0 ; r setRange( 0, 99 ); slider- setValue ( 0 ); connect ( slider, SIGNAL( valueChanged(int

40、), lcd, SLOT( display (int) ); 这里直接利用了第五章里面的 MyWidget 的构造函数 。 唯一的不同是按钮被省略了并且这个类被重新命名了。class MyWidget : public QVBox public: MyWidget( QWidget *parent=0, const char *name=0 ); ; MyWidget 也是除了一个构造函数之外没有包含任何 API。MyWidget:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) QPushButton

41、*quit = new QPushButton( “Quit“, this, “quit“ ); quit- setFont ( QFont( “Times“, 18, QFont:Bold ) ); connect ( quit, SIGNAL( clicked (), qApp, SLOT( quit () ); 这个按钮被放在 LCDRange 中,这样我们就有了一个“ Quit”按钮和许多LCDRange 对象。QGrid *grid = new QGrid( 4, this ); 我们创建了一个四列的 QGrid 对象。这个 QGrid 窗口部件可以自动地把自己地子窗口部件排列到行列

42、中, 你可以指定行和列的数量, 并且 QGrid 可以发现它的新子窗口部件并且把它们安放到网格中。for( int r = 0 ; r qvbox.h 被包含了。 LCDRange 继承了 QVBox ,所以父类的头文件必须被包含。我们在前几章里面偷了一点懒,我们通过包含其它一些头文件,比如qpushbutton.h,这样就可以间接地包含 qwidget.h。class QSlider; 这里是另外一个小伎俩, 但是没有前一个用的多。 因为我们在类的 界面 中不需要QSlider,仅仅是在实现中,我们在头文件中使用一个前置的类声明,并且在 .cpp文件中包含一个 QSlider 的头文件。这会

43、使编译一个大的项目变得更快, 因为当一个头文件改变的时候, 很少的文件需要重新编译。它通常可以给大型编译加速两倍或两倍以上。class LCDRange : public QVBox Q_OBJECTpublic: LCDRange( QWidget *parent=0, const char *name=0 ); meta object file. 注意 Q_OBJECT。这个宏必须被包含到 所有 使用信号和 /或槽的类。如果你很好奇,它定义了在 元对象文件 中实现的一些函数。int value() const; public slots: void setValue( int ); sig

44、nals: void valueChanged( int ); 这三个成员函数构成了这个窗口部件和程序中其它组件的接口。直到现在,LCDRange 根本没有一个真正的接口。value()是一个可以访问 LCDRange 的值的公共函数。 setValue()是我们第一个自定义槽,并且 valueChanged()是我们第一个自定义信号。槽必须按通常的方式实现 (记住槽也是一个 C+成员函数) 。 信号可以在 元对象文件中自动实现。 信号也遵守 C+函数的保护法则 (比如, 一个类只能发射它自己定义的或者继承来的信号)。当 LCDRange 的值发生变化时, valueChanged()信号就会

45、被使用你从这个名字中就可以猜到。这将不会是你将会看到的命名为 somethingChanged()的最后一个信号。t7/lcdrange.cpp这个文件主要利用了 t6/main.cpp,在这里只是说明一下改变了哪些。connect ( slider, SIGNAL( valueChanged(int), lcd, SLOT( display (int) ); connect ( slider, SIGNAL( valueChanged(int), SIGNAL(valueChanged(int) ); 这个代码来自 LCDRange 的构造函数。第一个 connect和你在上一章中看到的一样

46、。第二个是新的,它把滑块的valueChanged()信号和这个对象的 valueChanged信号 连接起来了。带有三个参数的 connect()函数连接到 this 对象的信号或槽。是的,这是正确的。信号可以被连接到其它的信号。当第一个信号被发射时,第二个信号也被发射。让我们来看看当用户操作这个滑块的时候都发生了些什么。 滑块看到自己的值发生了改变,并发射了 valueChanged()信号。这个信号被连接到 QLCDNumber 的display()槽和 LCDRange 的 valueChanged()信号。所以, 当这个信号被发射的时候, LCDRange 发射它自己的 valueChanged()信号。另外, QLCDNumber:display()被调用并显示新的数字。注意你并没有保证执行的任何顺序 LCDRange:valueChanged()也许在QLCDNumber:display() 之前或者之后发射,这是完全任意的。int LCDRange:value() const return slider- value (); value()的实现是直接了当的,它简单地返回滑块的值。void LCDRange:setValue( int value ) slider- setV

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

当前位置:首页 > 实用文档 > 简明教程

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报