收藏 分享(赏)

QT入门教程.pdf

上传人:精品资料 文档编号:8829441 上传时间:2019-07-13 格式:PDF 页数:61 大小:585.06KB
下载 相关 举报
QT入门教程.pdf_第1页
第1页 / 共61页
QT入门教程.pdf_第2页
第2页 / 共61页
QT入门教程.pdf_第3页
第3页 / 共61页
QT入门教程.pdf_第4页
第4页 / 共61页
QT入门教程.pdf_第5页
第5页 / 共61页
点击查看更多>>
资源描述

1、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.setMainWidget( hello.show(); return

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

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

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

5、一个窗口 (因为在构造函数指定 0 为它的父窗口,在这个父窗口中按钮被定位)。 hello.resize( 100, 30 ); 这个按酒被设置成 100 像素宽,30 像素高(加上窗口系统边框)。在这种情况下,我们不用考虑按钮的位置,并且我们接受默认值。 a.setMainWidget( 这个按钮被选为这个应用程序的主窗口部件。如果用户关闭了主窗口部件,应用程序就退出了。 你不用必须设置一个主窗口部件,但绝大多数程序都有一个。 hello.show(); 当你创建一个窗口部件的时候,它是不可见的。你必须调用 show()来使它变为可见的。 return a.exec(); 这里就是 main

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

7、在可以输入make (或者 nmake,如果你使用 Visual Studio),然后运行你的第一个Qt 应用程序! 行为 当你运行它的时候,你就会看到一个被单一按钮充满的小窗口,在它上面你可以读到著名的词:Hellow World! 练习 试着改变窗口的大小。按下按钮。如果你在 X 窗口下运行,使用-geometry 选项(比如,-geometry 100x200+10+20 )来运行这个程序。 现在你可以进行第二章 了。 Qt 教程一 第二章:调用退出 你已经在 第一章中创建了一个窗口,我们现在使这个应用程序在用户让它退出的时候退出。 我们也会使用一个比默认字体更好的一个字体。 /* *

8、* 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 ) ); QObject:connect( a.setMainWidget( quit.show(); return a.exec(); 一行一行地解说 #include 因为这个程序使

9、用了 QFont,所以它需要包含qfont.h。 Qt的字体提取和X 中提供的可怕的字体提取大为不同,字体的载入和使用都已经被高度优化了。 QPushButton quit( “Quit“, 0 ); 这时,按钮显示“Quit” ,确切的说这就是当用户点击这个按钮时程序所要做的。这不是一个巧合。因为这个按钮是一个顶层窗口,我们还是把 0 作为它的父对象。 quit.resize( 75, 30 ); 我们给这个按钮选择了另外一个大小,因为这个文本比 “Hello world!”小一些。我们也可以使用QFontMetrics来设置正确的大小。 quit.setFont( QFont( “Time

10、s“, 18, QFont:Bold ) ); 这里我们给这个按钮选择了一个新字体,Times 字体中的 18 点加粗字体。注意在这里我们调用了这个字体。 你也可以改变整个应用程序的默认字体(使用 QApplication:setFont())。 QObject:connect( connect也许是 Qt中 最重要 的特征了。注意 connect()是 QObject中的一个静态函数。不要把这个函数和socket 库中的 connect()搞混了。 这一行在两个 Qt对象(直接或间接继承QObject 对象的对象)中建立了一种单向的连接。每一个Qt对象都有signals (发送消息)和slo

11、ts(接收消息)。所有窗口部件都是Qt 对象。它们继承QWidget,而QWidget 继承 QObject。 这里 quit 的 clicked()信号和 a 的 quit()槽连接起来了,所以当这个按钮被按下的时候,这个程序就退出了。 信号和槽 文档详细描述了这一主题。 行为 当你运行这个程序的时候,你会看到这个窗口比第一章中的那个小一些,并且被一个更小的按钮充满。 (请看 编译 来学习如何创建一个makefile 和连编应用程序。) 练习 试着改变窗口的大小。按下按钮。注意!connect() 看起来会有一些不同。 是不是在 QPushButton中还有其它的你可以连接到 quit的信号

12、?提示:QPushButton继承了QButton的绝大多数行为。 现在你可以进行第三章 了。 Qt 教程一 第三章:家庭价值 这个例子演示了如何创建一个父窗口部件和子窗口部件。 我们将会保持这个程序的简单性,并且只使用一个单一的父窗口部件和一个独立的子窗口部件。 /* * * Qt 教程一 - 3 * */ #include #include #include #include int main( int argc, char *argv ) QApplication a( argc, argv ); QVBox box; box.resize( 200, 120 ); QPushButto

13、n quit( “Quit“, quit.setFont( QFont( “Times“, 18, QFont:Bold ) ); QObject:connect( a.setMainWidget( box.show(); return a.exec(); 一行一行地解说 #include 我们添加了一个头文件 qvbox.h 用来获得我们要使用的布局类。 QVBox box; 这里我们简单地创建了一个垂直的盒子容器。 QVBox把它的子窗口部件排成一个垂直的行,一个在其它的上面,根据每一个子窗口部件的QWidget:sizePolicy()来安排空间。 box.resize( 200, 12

14、0 ); 我们它的高设置为 120 像素,宽为 200 像素。 QPushButton quit( “Quit“, 子窗口部件产生了。 QPushButton通过一个文本(“text” )和一个父窗口部件(box )生成的。子窗口部件总是放在它的父窗口部件的最顶端。当它被显示的时候,它被父窗口部件的边界挡住了一部分。 父窗口部件,QVBox,自动地把这个子窗口部件添加到它的盒子中央。因为没有其它的东西被添加了,这个按钮就获得了父窗口部件的所有空间。 box.show(); 当父窗口部件被显示的时候,它会调用所有子窗口部件的显示函数(除非在这些子窗口部件中你已经明确地使用QWidget:hide

15、 ())。 行为 这个按钮不再充满整个窗口部件。相反,它获得了一个 “自然的” 大小。这是因为现在的这个新的顶层窗口,使用了按钮的大小提示和大小变化策略来设置这个按钮的大小和位置。(请看QWidget:sizeHint()和 QWidget:setSizePolicy()来获得关于这几个函数的更详细的信息。) (请看 编译 来学习如何创建一个makefile 和连编应用程序。) 练习 试着改变窗口的大小。按钮是如何变化的?按钮的大小变化策略是什么?如果你运行这个程序的时候使用了一个大一些的字体,按钮的高度发生了什么变化?如果你试图让这个窗口 真的 变小,发生了什么? 现在你可以进行第四章 了。

16、 Qt教程一 第四章:使用窗口部件 这个例子显示了如何创建一个你自己的窗口部件,描述如何控制一个窗口部件的最小大小和最大大小,并且介绍了窗口部件的名称。 /* * * Qt 教程一 - 4 * */ #include #include #include class MyWidget : public QWidget public: MyWidget( QWidget *parent=0, const char *name=0 ); ; MyWidget:MyWidget( QWidget *parent, const char *name ) : QWidget( parent, name )

17、 setMinimumSize( 200, 120 ); setMaximumSize( 200, 120 ); QPushButton *quit = new QPushButton( “Quit“, this, “quit“ ); quit-setGeometry( 62, 40, 75, 30 ); quit-setFont( QFont( “Times“, 18, QFont:Bold ) ); connect( quit, SIGNAL(clicked(), qApp, SLOT(quit() ); int main( int argc, char *argv ) QApplicat

18、ion a( argc, argv ); MyWidget w; w.setGeometry( 100, 100, 200, 120 ); a.setMainWidget( w.show(); return a.exec(); 一行一行地解说 class MyWidget : public QWidget public: MyWidget( QWidget *parent=0, const char *name=0 ); ; 这里我们创建了一个新类。因为这个类继承了 QWidget,所以新类是一个窗口部件,并且可以最为一个顶层窗口或者子窗口部件(像第三章里面的按钮)。 这个类只有一个成员函数,

19、构造函数(加上从 QWidget 继承来的成员函数)。这个构造函数是一个标准的 Qt 窗口部件构造函数,当你创建窗口部件时,你应该总是包含一个相似的构造函数。 第一个参数是它的父窗口部件。为了生成一个顶层窗口,你指定一个空指针作为父窗口部件。就像你看到的那样,这个窗口部件默认地被认做是一个顶层窗口。 第二个参数是这个窗口部件的名称。这个 不是 显示在窗口标题栏或者按钮上的文本。这只是分配给窗口部件的一个名称,以后可以用来 查找 这个窗口部件,并且这里还有一个 方便的调试功能可以完整地列出窗口部件层次。 MyWidget:MyWidget( QWidget *parent, const char

20、 *name ) : QWidget( parent, name ) 构造函数的实现从这里开始。像大多数窗口部件一样,它把parent 和name 传递给了 QWidget的构造函数。 setMinimumSize( 200, 120 ); setMaximumSize( 200, 120 ); 因为这个窗口部件不知道如何处理重新定义大小,我们把它的最小大小和最大大小设置为相等的值,这样我们就确定了它的大小。在下一章,我们将演示窗口部件如何响应用户的重新定义大小事件。 QPushButton *quit = new QPushButton( “Quit“, this, “quit“ ); qu

21、it-setGeometry( 62, 40, 75, 30 ); quit-setFont( QFont( “Times“, 18, QFont:Bold ) ); 这里我们创建并设置了这个窗口部件的一个名称为“quit” 的子窗口部件(新窗口部件的父窗口部件是 this)。这个窗口部件名称和按钮文本没有关系,只是在这一情况下碰巧相似。 注意 quit是这个构造函数中的局部变量。MyWidget 不能跟踪它,但 Qt可以,当MyWidget 被删除的时候,默认地它也会被删除。这就是为什么 MyWidget 不需要一个析构函数的原因。(另外一方面,如果你选择删除一个子窗口部件,也没什么坏处,这

22、个子窗口部件会自动告诉 Qt 它即将死亡。) setGeometry()调用和上一章的 move()和 resize()是一样的。 connect( quit, SIGNAL(clicked(), qApp, SLOT(quit() ); 因为 MyWidget 类不知道这个应用程序对象,它不得不连接到 Qt 的指针,qApp。 一个窗口部件就是一个软件组件并且它应该尽量少地知道关于它的环境,因为它应该尽可能的通用和可重用。 知道了应用程序的名称将会打破上述原则,所以在一个组件,比如 MyWidget,需要和应用程序对象对话的这种情况下,Qt 提供了一个别名,qApp。 int main( i

23、nt argc, char *argv ) QApplication a( argc, argv ); MyWidget w; w.setGeometry( 100, 100, 200, 120 ); a.setMainWidget( w.show(); return a.exec(); 这里我们举例说明了我们的新子窗口部件,把它设置为主窗口部件,并且执行这个应用程序。 行为 这个程序和上一章的在行为上非常相似。不同点是我们实现的方式。无论如何它的行为还是有一些小差别。试试改变它的大小,你会看到什么? (请看 编译 来学习如何创建一个makefile 和连编应用程序。) 练习 试着在 main

24、()中创建另一个 MyWidget 对象。发生了什么? 试着添加更多的按钮或者把除了 QPushButton之外的东西放到窗口部件中。 现在你可以进行第五章 了。 Qt 教程一 第五章:组装积木 这个例子显示了创建几个窗口部件并用信号和槽把它们连接起来,和如何处理重新定义大小事件。 /* * * Qt 教程一 - 5 * */ #include #include #include #include #include #include class MyWidget : public QVBox public: MyWidget( QWidget *parent=0, const char *na

25、me=0 ); ; MyWidget:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) QPushButton *quit = new QPushButton( “Quit“, this, “quit“ ); quit-setFont( QFont( “Times“, 18, QFont:Bold ) ); connect( quit, SIGNAL(clicked(), qApp, SLOT(quit() ); QLCDNumber *lcd = new QLCDNumber( 2, this, “lc

26、d“ ); QSlider * slider = new QSlider( Horizontal, this, “slider“ ); slider-setRange( 0, 99 ); slider-setValue( 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

27、(); 一行一行地解说 #include #include #include #include #include #include 这里显示的是三个新的被包含的头文件。 qslider.h和 qlcdnumber.h在这里是因为我们使用了两个新的窗口部件,QSlider 和QLCDNumber 。qvbox.h 在这里是因为我们使用了 Qt的自动布局支持。 class MyWidget : public QVBox blic: get( QWidget *parent=0, const char *name=0 ); idget:MyWidget( QWidget *parent, const

28、 char *name ) MyWidget现在继承了 QVBox,而不是 QWidget。我们通过这种方式来使用 QVBox的布局(它可QLCDNumber *lcd = new QLCDNumber( 2, this, “lcd“ ); lcd 是一个 QLCDNumber,一个可以按像 LCD 的方式显示数字的窗口部件。这QSlider * slider = new QSlider( Horizontal, this, “slider“ ); QSlider是一个经典的滑块,用户可以通过在拖动一个东西在一定范围内调节一个整数数值的方connect( slider, SIGNAL(valu

29、eChanged(int), lcd, SLOT(display(int) ); 这里我们是用了信号 /槽机制把滑块的valueChanged() 信号和LCD 数字的 display()槽连接起来了。 么时候滑块的值发生了变化,它都会通过发射 valueChanged()信号来广播这个新的值。因为这个信号已经和 LCD 数字的 display()槽连接起来了,当信号方式不同,但有着普通 C+成员函数的方位规则。 puMyWid; MyW: QVBox( parent, name ) 以把它的子窗口部件垂直地放在自己里面)。重新定义大小自动地被 QVBox处理,因此现在也就被MyWidget

30、处理了。 个实例被设置为显示两个数字,并且是 this 的子窗口部件。它被命名为“lcd” 。 slider-setRange( 0, 99 ); slider-setValue( 0 ); 式来使用这个窗口部件。这里我们创建了一个水平的滑块,设置它的范围是 099(包括 0和 99,参见 QSlider:setRange()文档)并且它的初始值是 0。 无论什被广播的时候,这个槽就被调用了。这两个对象中的任何一个都不知道对方。这就是组件编程的本质。 槽是和普通 C+成员函数的行为 LCD 数字反大小事件。应了你对滑块做的一切,并且这个窗口部件很好地处理了重新定义注意当窗口被重新定义大小(因为

31、它可以)的时候,LDC 数字窗口部件也改变了大小,但是其它的还是和原来一样(因为如果它们变化了,看起来练习 数字,添加更多的数字或者改变模式。你甚至可以添加四个按钮来设置基数。 你也可以改变滑块的范围。 也许使用 QSpinBox比滑块更好? 试着当 LCD 数字溢出的时候使这个应用程序退出。 现在你可以进行第六章了。 Qt教程一 第六章:组装丰富的积好像很傻)。 (请看编译来学习如何创建一个makefile 和连编应用程序。) 试着改变 LCD木! 这个例子显示了如何把两个窗口部件封装成一个新的组件和使用许多窗口部件是多么的容易。首先,我们使用一个自定义的窗口部件作为一个子窗口部件。 * Q

32、t 教程一 - 6 */ /* * * *#include include blic QVBox ublic: 0, const char *name=0 ); : QVBox( parent, name ) ( Horizontal, this, “slider“ ); slider-setRange( 0, 99 ); ay(int) ); ublic: 0, const char *name=0 ); idget:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) “ ); , 18, QFont:B

33、old ) ); QGrid *grid = new QGrid( 4, this ); for( int r = 0 ; r #include #include #include #include class LCDRange : pu pLCDRange( QWidget *parent=; LCDRange:LCDRange( QWidget *parent, const char *name ) QLCDNumber *lcd = new QLCDNumber( 2, this, “lcd“ ); QSlider * slider = new QSliderslider-setValu

34、e( 0 ); connect( slider, SIGNAL(valueChanged(int), lcd, SLOT(displ class MyWidget : public QVBox pMyWidget( QWidget *parent=; MyWQPushButton *quit = new QPushButton( “Quit“, this, “quitquit-setFont( QFont( “Times“connect( quit, SIGNAL(clicked(), qApp, SLOT(quit() ); for( int c = 0 ; c setRange( 0, 9

35、9 ); ay(int) ); 略了并且这个类被了。 public: 0, const char *name=0 ); API。 int main( int argc, char *argv ) a.setMainWidget( return a.exec(); 一行一行地class LCDRange : public QVBox LCDRange( QWidget *parent=; LCDRange窗口部件是一个没有任何 API的窗口部件种窗口LCDRange:LCDRange( QWidget *parent, const char *name ) : QVBox( parent, na

36、me ) QLCDNumber *lcd = new QLCDNumber( 2, this, “lcd“ )QSlider * slider = new QSlidersslider-setValue( 0 ); connect( slider, SIGNAL(valueChanged(int), lcd, SLOT(displ 这里直接利用了第五章里面的MyWidget 的构造函数 。唯一的不同是按钮被省重新命名class MyWidget : public QVBox MyWidget( QWidget *parent=; MyWidget 也是除了一个构造函数之外没有包含任何MyWid

37、get:MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name ) QPushButton *quit = new QPushButton( “Quit“, this, “quit“ ); connect( quit, SIGNAL(clicked(), qApp, SLOT(quit() ); 一个“Quit” 按钮和许多CDRange 对象。 QGrid *grid = new QGrid( 4, this ); Grid对象。这个 QGrid窗口部件可以自动地把自己地子窗口部件排列到行列中,你可以指定行和列的

38、数量,并且 QGrid可以发现它的新子窗口部件并且把它们安放到(void)new LCDRange( grid ); 些都是这个 grid 对象的子窗口部件。这个 QGrid 窗口部件会安排它们。 这个程序显示了在同一时间使用许多窗口部件是多么的容易。其中的滑块和行为在前一章已经提到过了。还有就是,就是实现的不同。 (请看编译来学习如何创建一个makefile 和连编应用程序。) 在开始的时候使用不同的或者随机的值初始化每个滑块。 ”出现了 3 次。如果你改变 QGrid构造函数中调用的那个,会发生什么?改变另外两个又会发生什么呢?为什么呢? quit-setFont( QFont( “Tim

39、es“, 18, QFont:Bold ) ); 这个按钮被放在 LCDRange 中,这样我们就有了L我们创建了一个四列的 Q网格中。 for( int r = 0 ; r 面偷了一点懒,我们通过包这里是另外一个小伎俩,但是没有前一个用的多。因为我们在类的界面 中不需要 QSlider,仅仅是在实现中,我们在头文件中使用一个前置的类声明,并且在.cpp 文件中包含一个 QSlider的头文件。 这会使编译一个大的项目变得更快,因为当一个头文件改变的时候,很少的文件需要重新编译。它通常可以给大型编译加速两倍或两倍以上。 Q_OBJECT 个宏必须被包含到 所有 使用信号和 /或槽的类。如果你很

40、好义了在元对象文件中实现的一些函数。 alue() const; void setValue( int ); void valueChanged( int ); 构成了这个窗口部件和程序中其它组件的接口。直到现在,正的接口。 可以访问 LCDRange 的值的公共函数。setValue() 是我们第一个自们第一个自定义信号。 类只能发射它自己定义的或者继承来的信号)。 用你从这个名字中就可以猜到。这将不会是你将会看到的命名为 somethingChanged()的最后p lider, SIGNAL(valueChanged(int), lcd, SLOT(display(int) ); der

41、, SIGNAL(valueChanged(int), SIGNAL(valueChanged(int) ); class LCDRange : public QVBox public: LCDRange( QWidget *parent=0, const char *name=0 ); meta object file. 注意 Q_OBJECT。这奇,它定int vpublic slots: signals: 这三个成员函数LCDRange 根本没有一个真value()是一个定义槽,并且 valueChanged()是我槽必须按通常的方式实现(记住槽也是一个C+成员函数)。信号可以在元对象文

42、件中自动实现。信号也遵守C+函数的保护法则(比如,一个当 LCDRange 的值发生变化时,valueChanged() 信号就会被使一个信号。 t7/lcdrange.cp这个文件主要利用了 t6/main.cpp,在这里只是说明一下改变了哪些。 connect( sconnect( sli这个代码来自 LCDRange 的构造函数。 第一个 connect 和你在上一章中看到的一样。第二个是新的,它把滑块的 valueChanged()信号和数的 connect()函数连接到 this 对象的信号或槽。 是的,这是正确的。信号可以被连接到其它的信号。当第一个信号被发射时,看当用户操作这个滑

43、块的时候都发生了些什么。滑块看到自己的值发生了改变,并发射了 valueChanged()信号。这个信号被连接到 QLCDNumber的display()槽和LCDRange 的所以,当这个信号被发射的时候,LCDRange 发射它自己的 valueChanged()信号。另外,行的任何顺序LCDRange:valueChanged() 也许在QLCDNumber:display()之前或者之后发射,这是完全任意的。 简单地返回滑块的值。 lue( int value ) slider-setValue( value ); 因为滑块和 LCD 数字是连接的,设置值就会自动的改变 LCD 数字的

44、值。另外,如果滑块的值超过了合法范t7/main.cpp 4 ; r+ ) for( int c = 0 ; c value(); value()的实现是直接了当的,它void LCDRange:setVa setValue()的实现是相当直接了当的。注意滑块的围,它会自动调节。 LCDRange *previous = 0; for( int r = 0 ; r 99 | minVal maxVal ) qWarning( “LCDRange:setRange(%d,%d)n“ “tRange must be 099n“ “tand minVal must not be greater th

45、an maxVal“, minVal, maxVal ); return; slider-setRange( minVal, maxVal ); setRange()设置了 LCDRange中滑块的范围。因为我们已经把 QLCDNumber设置为只显示两位数字了,我们想通过限制minVal 和maxVal 为 099 来避免 QLCDNumber的溢出。(我们可以允许最小值为 -9,但是我们没有那样做。)如果参数是非法的,我们使用Qt 的qWarning ()函数来向用户发出警告并立即返回。 qWarning()是一个像 printf一样的函数,默认情况下它的输出发送到stderr。如果你想改

46、变的话,你可以使用 :qInstallMsgHandler()函数安装自己的处理函数。 t8/cannon.h CanonField 是一个知道如何显示自己的新的自定义窗口部件。 class CannonField : public QWidget Q_OBJECT public: CannonField( QWidget *parent=0, const char *name=0 ); CanonField继承了QWidget ,我们使用了 LCDRange中同样的方式。 int angle() const return ang; QSizePolicy sizePolicy() const; public slots: void setAngle( int degrees ); signals: void angleChanged( int ); 目前,CanonField 只包含一个角度值,我们使用了 LCDRange 中同样的方式。 protected: void paintEvent( QPaintEvent * ); 这是我们在 QWidget 中遇到的许多事件处理器中的第二个。只要

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

当前位置:首页 > 企业管理 > 管理学资料

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


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

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

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