summaryrefslogtreecommitdiffstats
path: root/doc/html/tutorial1-12.html
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /doc/html/tutorial1-12.html
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'doc/html/tutorial1-12.html')
-rw-r--r--doc/html/tutorial1-12.html328
1 files changed, 328 insertions, 0 deletions
diff --git a/doc/html/tutorial1-12.html b/doc/html/tutorial1-12.html
new file mode 100644
index 0000000..6964044
--- /dev/null
+++ b/doc/html/tutorial1-12.html
@@ -0,0 +1,328 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/tutorial.doc:1711 -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Qt Tutorial - Chapter 12: Hanging in the Air the Way Bricks Don't</title>
+<style type="text/css"><!--
+fn { margin-left: 1cm; text-indent: -1cm; }
+a:link { color: #004faf; text-decoration: none }
+a:visited { color: #672967; text-decoration: none }
+body { background: #ffffff; color: black; }
+--></style>
+</head>
+<body>
+
+<table border="0" cellpadding="0" cellspacing="0" width="100%">
+<tr bgcolor="#E5E5E5">
+<td valign=center>
+ <a href="index.html">
+<font color="#004faf">Home</font></a>
+ | <a href="classes.html">
+<font color="#004faf">All&nbsp;Classes</font></a>
+ | <a href="mainclasses.html">
+<font color="#004faf">Main&nbsp;Classes</font></a>
+ | <a href="annotated.html">
+<font color="#004faf">Annotated</font></a>
+ | <a href="groups.html">
+<font color="#004faf">Grouped&nbsp;Classes</font></a>
+ | <a href="functions.html">
+<font color="#004faf">Functions</font></a>
+</td>
+<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Qt Tutorial - Chapter 12: Hanging in the Air the Way Bricks Don't</h1>
+
+
+<p> <center><img src="t12.png" alt="Screenshot of tutorial twelve"></center>
+<p> In this example, we extend our LCDRange class to include a text label.
+We also provide something to shoot at.
+<p> <ul>
+<li> <a href="t12-lcdrange-h.html">t12/lcdrange.h</a> contains the LCDRange
+class definition.
+<li> <a href="t12-lcdrange-cpp.html">t12/lcdrange.cpp</a> contains the LCDRange
+implementation.
+<li> <a href="t12-cannon-h.html">t12/cannon.h</a> contains the CannonField class
+definition.
+<li> <a href="t12-cannon-cpp.html">t12/cannon.cpp</a> contains the CannonField
+implementation.
+<li> <a href="t12-main-cpp.html">t12/main.cpp</a> contains MyWidget and main.
+</ul>
+<p> <h2> Line-by-line Walkthrough
+</h2>
+<a name="1"></a><p> <h3> <a href="t12-lcdrange-h.html">t12/lcdrange.h</a>
+</h3>
+<a name="1-1"></a><p> The LCDRange now has a text label.
+<p>
+
+<p> <pre> class QLabel;
+</pre>
+<p> We name declare <a href="qlabel.html">QLabel</a> because we want to use a pointer to it in the class
+definition.
+<p> <pre> class LCDRange : public <a href="qvbox.html">QVBox</a>
+ {
+ <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a>
+ public:
+ LCDRange( <a href="qwidget.html">QWidget</a> *parent=0, const char *name=0 );
+ LCDRange( const char *s, QWidget *parent=0,
+ const char *name=0 );
+</pre>
+<p> We have added a new constructor that sets the label text in addition to
+the parent and name.
+<p> <pre> const char *text() const;
+</pre>
+<p> This function returns the label text.
+<p> <pre> void setText( const char * );
+</pre>
+<p> This slot sets the label text.
+<p> <pre> private:
+ void init();
+</pre>
+<p> Because we now have two constructors, we have chosen to put the common
+initialization in the private init() function.
+<p> <pre> <a href="qlabel.html">QLabel</a> *label;
+</pre>
+<p> We also have a new private variable: a QLabel. QLabel is one of Qt's
+standard widgets and can show a text or a pixmap with or without a
+frame.
+<p> <h3> <a href="t12-lcdrange-cpp.html">t12/lcdrange.cpp</a>
+</h3>
+<a name="1-2"></a><p>
+
+<p> <pre> #include &lt;<a href="qlabel-h.html">qlabel.h</a>&gt;
+</pre>
+<p> Here we include the <a href="qlabel.html">QLabel</a> class definition.
+<p> <pre> LCDRange::LCDRange( <a href="qwidget.html">QWidget</a> *parent, const char *name )
+ : <a href="qvbox.html">QVBox</a>( parent, name )
+ {
+ init();
+ }
+</pre>
+<p> This constructor calls the init() function, which contains the common
+initialization code.
+<p> <pre> LCDRange::LCDRange( const char *s, QWidget *parent,
+ const char *name )
+ : <a href="qvbox.html">QVBox</a>( parent, name )
+ {
+ init();
+ setText( s );
+ }
+</pre>
+<p> This constructor first calls init() and then sets the label text.
+<p> <pre> void LCDRange::init()
+ {
+ <a href="qlcdnumber.html">QLCDNumber</a> *lcd = new <a href="qlcdnumber.html">QLCDNumber</a>( 2, this, "lcd" );
+ slider = new <a href="qslider.html">QSlider</a>( Horizontal, this, "slider" );
+ <a name="x2387"></a> slider-&gt;<a href="qrangecontrol.html#setRange">setRange</a>( 0, 99 );
+ <a name="x2388"></a> slider-&gt;<a href="qslider.html#setValue">setValue</a>( 0 );
+
+ label = new <a href="qlabel.html">QLabel</a>( " ", this, "label" );
+ <a name="x2383"></a> label-&gt;<a href="qlabel.html#setAlignment">setAlignment</a>( AlignCenter );
+
+ <a name="x2389"></a> <a href="qobject.html#connect">connect</a>( slider, SIGNAL(<a href="qslider.html#valueChanged">valueChanged</a>(int)),
+ <a name="x2386"></a> lcd, SLOT(<a href="qlcdnumber.html#display">display</a>(int)) );
+ <a href="qobject.html#connect">connect</a>( slider, SIGNAL(<a href="qslider.html#valueChanged">valueChanged</a>(int)),
+ SIGNAL(valueChanged(int)) );
+
+ <a href="qwidget.html#setFocusProxy">setFocusProxy</a>( slider );
+ }
+</pre>
+<p> The setup of <tt>lcd</tt> and <tt>slider</tt> is the same as in the previous
+chapter. Next we create a <a href="qlabel.html">QLabel</a> and tell it to align the contents
+centered (both vertically and horizontally). The connect() statements
+have also been taken from the previous chapter.
+<p> <pre> const char *LCDRange::text() const
+ {
+ <a name="x2385"></a> return label-&gt;<a href="qlabel.html#text">text</a>();
+ }
+</pre>
+<p> This function returns the label text.
+<p> <pre> void LCDRange::setText( const char *s )
+ {
+ <a name="x2384"></a> label-&gt;<a href="qlabel.html#setText">setText</a>( s );
+ }
+</pre>
+<p> This function sets the label text.
+<p> <h3> <a href="t12-cannon-h.html">t12/cannon.h</a>
+</h3>
+<a name="1-3"></a><p> The CannonField now has two new signals: hit() and missed(). In addition
+it contains a target.
+<p>
+
+<p> <pre> void newTarget();
+</pre>
+<p> This slot creates a target at a new position.
+<p> <pre> signals:
+ void hit();
+ void missed();
+</pre>
+<p> The hit() signal is emitted when a shot hits the target. The missed()
+signal is emitted when the shot moves beyond the right or bottom edge
+of the widget (i.e., it is certain that it has not and will not
+hit the target).
+<p> <pre> void paintTarget( <a href="qpainter.html">QPainter</a> * );
+</pre>
+<p> This private function paints the target.
+<p> <pre> <a href="qrect.html">QRect</a> targetRect() const;
+</pre>
+<p> This private function returns the enclosing rectangle of the target.
+<p> <pre> <a href="qpoint.html">QPoint</a> target;
+</pre>
+<p> This private variable contains the center point of the target.
+<p> <h3> <a href="t12-cannon-cpp.html">t12/cannon.cpp</a>
+</h3>
+<a name="1-4"></a><p>
+
+<p> <pre> #include &lt;<a href="qdatetime-h.html">qdatetime.h</a>&gt;
+</pre>
+<p> We include the <a href="qdate.html">QDate</a>, <a href="qtime.html">QTime</a>, and <a href="qdatetime.html">QDateTime</a> class definitions.
+<p> <pre> #include &lt;stdlib.h&gt;
+</pre>
+<p> We include the stdlib library because we need the rand() function.
+<p> <pre> newTarget();
+</pre>
+<p> This line has been added to the constructor. It creates a "random"
+position for the target. In fact, the newTarget() function will try
+to paint the target. Because we are in a constructor, the CannonField
+widget is invisible. Qt guarantees that no harm is done when calling
+repaint() on a hidden widget.
+<p> <pre> void CannonField::newTarget()
+ {
+ static bool first_time = TRUE;
+ if ( first_time ) {
+ first_time = FALSE;
+ <a href="qtime.html">QTime</a> midnight( 0, 0, 0 );
+ <a name="x2399"></a><a name="x2398"></a> srand( midnight.<a href="qtime.html#secsTo">secsTo</a>(QTime::<a href="qtime.html#currentTime">currentTime</a>()) );
+ }
+ <a href="qregion.html">QRegion</a> r( targetRect() );
+ target = QPoint( 200 + rand() % 190,
+ 10 + rand() % 255 );
+ <a name="x2395"></a> <a href="qwidget.html#repaint">repaint</a>( r.<a href="qrect.html#unite">unite</a>( targetRect() ) );
+ }
+</pre>
+<p> This private function creates a target center point at a new "random"
+position.
+<p> We use the rand() function to fetch random integers. The rand() function
+normally returns the same series of numbers each time you run a program.
+This would make the target appear at the same position every time. To
+avoid this, we must set a random seed the first time this function is
+called. The random seed must also be random in order to avoid equal random
+number series. The solution is to use the number of seconds that have
+passed since midnight as a pseudo-random value.
+<p> First we create a static bool local variable. A static variable like
+this one is guaranteed to keep its value between calls to the function.
+<p> The <tt>if</tt> test will succeed only the first time this function is called
+because we set <tt>first_time</tt> to FALSE inside the <tt>if</tt> block.
+<p> Then we create the <a href="qtime.html">QTime</a> object <tt>midnight</tt>, which represents the time
+00:00:00. Next we fetch the number of seconds from midnight until
+now and use it as a random seed. See the documentation for <a href="qdate.html">QDate</a>,
+<a href="qtime.html">QTime</a>, and <a href="qdatetime.html">QDateTime</a> for more information.
+<p> Finally we calculate the target's center point. We keep it within
+the rectangle (x=200, y=35, width=190, height=255), (i.e., the
+possible x and y values are x = 200..389 and y = 35..289) in a
+coordinate system where we put y position 0 at the bottom edge of the
+widget and let y values increase upwards X is as normal, with 0 at
+the left edge and with x values increasing to the right.
+<p> By experimentation we have found this to always be in reach of the shot.
+<p> Note that rand() returns a random integer >= 0.
+<p> <pre> void CannonField::moveShot()
+ {
+ <a href="qregion.html">QRegion</a> r( shotRect() );
+ timerCount++;
+
+ <a href="qrect.html">QRect</a> shotR = shotRect();
+</pre>
+<p> This part of the timer event has not changed from the previous chapter.
+<p> <pre> if ( shotR.<a href="qrect.html#intersects">intersects</a>( targetRect() ) ) {
+ <a name="x2400"></a> autoShootTimer-&gt;<a href="qtimer.html#stop">stop</a>();
+ emit hit();
+</pre>
+<p> This <tt>if</tt> statement checks whether the shot rectangle intersects the
+target rectangle. If it does, the shot has hit the target (ouch!).
+We stop the shoot timer and emit the hit() signal to tell the outside
+world that a target was destroyed, and return.
+<p> Note that we could have created a new target on the spot, but because the
+CannonField is a component we leave such decisions to the user of the
+component.
+<p> <pre> <a name="x2397"></a><a name="x2396"></a> } else if ( shotR.<a href="qrect.html#x">x</a>() &gt; width() || shotR.<a href="qrect.html#y">y</a>() &gt; height() ) {
+ autoShootTimer-&gt;<a href="qtimer.html#stop">stop</a>();
+ emit missed();
+</pre>
+<p> This <tt>if</tt> statement is the same as in the previous chapter, except that
+it now emits the missed() signal to tell the outside world about the
+failure.
+<p> <pre> } else {
+</pre>
+<p> And the rest of the function is as before.
+<p> CannonField::paintEvent() is as before, except that this has been
+added:
+<p> <pre> <a name="x2393"></a> if ( updateR.<a href="qrect.html#intersects">intersects</a>( targetRect() ) )
+ paintTarget( &amp;p );
+</pre>
+<p> These two lines make sure that the target is also painted when necessary.
+<p> <pre> void CannonField::paintTarget( <a href="qpainter.html">QPainter</a> *p )
+ {
+ p-&gt;<a href="qpainter.html#setBrush">setBrush</a>( red );
+ p-&gt;<a href="qpainter.html#setPen">setPen</a>( black );
+ p-&gt;<a href="qpainter.html#drawRect">drawRect</a>( targetRect() );
+ }
+</pre>
+<p> This private function paints the target; a rectangle filled with red and
+with a black outline.
+<p> <pre> QRect CannonField::targetRect() const
+ {
+ <a href="qrect.html">QRect</a> r( 0, 0, 20, 10 );
+ <a name="x2394"></a> r.<a href="qrect.html#moveCenter">moveCenter</a>( QPoint(target.x(),height() - 1 - target.y()) );
+ return r;
+ }
+</pre>
+<p> This private function returns the enclosing rectangle of the target.
+Remember from newTarget() that the <tt>target</tt> point uses y coordinate 0 at
+the bottom of the widget. We calculate the point in widget coordinates
+before we call <a href="qrect.html#moveCenter">QRect::moveCenter</a>().
+<p> The reason we have chosen this coordinate mapping is to fix the distance
+between the target and the bottom of the widget. Remember that the widget
+can be resized by the user or the program at any time.
+<p> <h3> <a href="t12-main-cpp.html">t12/main.cpp</a>
+</h3>
+<a name="1-5"></a><p>
+
+<p> There are no new members in the MyWidget class, but we have slightly
+changed the constructor to set the new LCDRange text labels.
+<p> <pre> LCDRange *angle = new LCDRange( "ANGLE", this, "angle" );
+</pre>
+<p> We set the angle text label to "ANGLE".
+<p> <pre> LCDRange *force = new LCDRange( "FORCE", this, "force" );
+</pre>
+<p> We set the force text label to "FORCE".
+<p> <h2> Behavior
+</h2>
+<a name="2"></a><p> The LCDRange widgets look a bit strange - the built-in layout
+management in <a href="qvbox.html">QVBox</a> gives the labels too much space and the rest not
+enough. We'll fix that in the next chapter.
+<p> (See <a href="tutorial1-07.html#compiling">Compiling</a> for how to create a
+makefile and build the application.)
+<p> <h2> Exercises
+</h2>
+<a name="3"></a><p> Make a cheat button that, when pressed, makes the CannonField display
+the shot trajectory for five seconds.
+<p> If you did the "round shot" exercise from the previous chapter, try
+changing the shotRect() to a shotRegion() that returns a <a href="qregion.html">QRegion</a> so
+you can have really accurate collision detection.
+<p> Make a moving target.
+<p> Make sure that the target is always created entirely on-screen.
+<p> Make sure that the widget cannot be resized so that the target isn't
+visible. Hint: <a href="qwidget.html#setMinimumSize">QWidget::setMinimumSize</a>() is your friend.
+<p> Not easy; make it possible to have several shots in the air at the
+same time. Hint: make a Shot object.
+<p> You're now ready for <a href="tutorial1-13.html">Chapter 13.</a>
+<p> [<a href="tutorial1-11.html">Previous tutorial</a>]
+[<a href="tutorial1-13.html">Next tutorial</a>]
+[<a href="tutorial.html">Main tutorial page</a>]
+<p>
+<!-- eof -->
+<p><address><hr><div align=center>
+<table width=100% cellspacing=0 border=0><tr>
+<td>Copyright &copy; 2007
+<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
+<td align=right><div align=right>Qt 3.3.8</div>
+</table></div></address></body>
+</html>