⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qt教程一 —— 第十四章:面对墙壁.htm

📁 嵌入式QT开发系列文档
💻 HTM
📖 第 1 页 / 共 2 页
字号:
</PRE>
<P>这是另外一个Qt事件处理器。当用户已经在窗口部件中按下了鼠标按键并且移动/拖拽鼠标时,它被调用。(你可以让Qt在没有鼠标按键被按下的时候发送鼠标移动事件。请看<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html#setMouseTracking">QWidget::setMouseTracking</A>()。) 

<P>这个处理器根据鼠标指针的位置重新配置加农炮的炮筒。 
<P>首先,如果炮筒没有被按下,我们返回。接下来,我们获得鼠标指针的位置。如果鼠标指针到了窗口部件的左面或者下面,我们调整鼠标指针使它返回到窗口部件中。 
<P>然后我们计算在鼠标指针和窗口部件的左下角所构成的虚构的线和窗口部件下边界的角度。最后,我们把加农炮的角度设置为我们新算出来的角度。 
<P>记住要用setAngle()来重新绘制加农炮。 
<P><PRE>    <A name=x2364></A>void CannonField::<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html#mouseReleaseEvent">mouseReleaseEvent</A>( <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qmouseevent.html">QMouseEvent</A> *e )
    {
    <A name=x2349></A>    if ( e-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qmouseevent.html#button">button</A>() == LeftButton )
            barrelPressed = FALSE;
    }
</PRE>
<P>只要用户释放鼠标按钮并且它是在窗口部件中按下的时候,这个Qt事件处理器就会被调用。 
<P>如果鼠标左键被释放,我们就会确认炮筒不再被按下了。 
<P>绘画事件包含了下述额外的两行: 
<P><PRE>    <A name=x2359></A>    if ( updateR.<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qrect.html#intersects">intersects</A>( barrierRect() ) )
            paintBarrier( &amp;p );
</PRE>
<P>paintBarrier()做的和paintShot()、paintTarget()和paintCannon()是同样的事情。 
<P><PRE>    void CannonField::paintBarrier( <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpainter.html">QPainter</A> *p )
    {
        p-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpainter.html#setBrush">setBrush</A>( yellow );
        p-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpainter.html#setPen">setPen</A>( black );
        p-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpainter.html#drawRect">drawRect</A>( barrierRect() );
    }
</PRE>
<P>这个私有函数用一个黑色边界黄色填充的矩形作为障碍物。 
<P><PRE>    QRect CannonField::barrierRect() const
    {
        return QRect( 145, height() - 100, 15, 100 );
    }
</PRE>
<P>这个私有函数返回障碍物的矩形。我们把障碍物的下边界和窗口部件的下边界放在了一起。 
<P><PRE>    bool CannonField::barrelHit( const <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpoint.html">QPoint</A> &amp;p ) const
    {
        <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html">QWMatrix</A> mtx;
    <A name=x2368></A>    mtx.<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html#translate">translate</A>( 0, height() - 1 );
    <A name=x2367></A>    mtx.<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html#rotate">rotate</A>( -ang );
    <A name=x2365></A>    mtx = mtx.<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html#invert">invert</A>();
    <A name=x2366></A><A name=x2358></A>    return barrelRect.<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qrect.html#contains">contains</A>( mtx.<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html#map">map</A>(p) );
    }
</PRE>
<P>如果点在炮筒内,这个函数返回TRUE;否则它就返回FALSE。 
<P>这里我们使用<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html">QWMatrix</A>类。它是在头文件qwmatrix.h中定义的,这个头文件被qpainter.h包含。 

<P><A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwmatrix.html">QWMatrix</A>定义了一个坐标系统映射。它可以执行和<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpainter.html">QPainter</A>中一样的转换。 

<P>这里我们实现同样的转换的步骤就和我们在paintCannon()函数中绘制炮筒的时候所作的一样。首先我们转换坐标系统,然后我们旋转它。 
<P>现在我们需要检查点<TT>p</TT>(在窗口部件坐标系统中)是否在炮筒内。为了做到这一点,我们倒置这个转换矩阵。倒置的矩阵就执行了我们在绘制炮筒时使用的倒置的转换。我们通过使用倒置矩阵来映射点<TT>p</TT>,并且如果它在初始的炮筒矩形内就返回TRUE。 

<P>
<H3><A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t14-gamebrd-cpp.html">t14/gamebrd.cpp</A> 
</H3><A name=1-3></A>
<P>
<P><PRE>    #include &lt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel-h.html">qaccel.h</A>&gt;
</PRE>
<P>我们包含<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html">QAccel</A>的类定义。 
<P><PRE>        <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A> *box = new <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A>( this, "cannonFrame" );
        box-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qframe.html#setFrameStyle">setFrameStyle</A>( QFrame::WinPanel | QFrame::Sunken );
        cannonField = new CannonField( box, "cannonField" );
</PRE>
<P>我们创建并设置一个<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A>,设置它的框架风格,并在之后创建<TT>CannonField</TT>作为这个盒子的子对象。因为没有其它的东西在这个盒子里了,效果就是<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A>会在CannonField周围生成了一个框架。 

<P><PRE>        <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html">QAccel</A> *accel = new <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html">QAccel</A>( this );
    <A name=x2370></A><A name=x2369></A>    accel-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html#connectItem">connectItem</A>( accel-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html#insertItem">insertItem</A>( Key_Enter ),
                            this, SLOT(fire()) );
        accel-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html#connectItem">connectItem</A>( accel-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html#insertItem">insertItem</A>( Key_Return ),
                            this, SLOT(fire()) );
</PRE>
<P>现在我们创建并设置一个加速键。加速键就是在应用程序中截取键盘事件并且如果特定的键被按下的时候调用相应的槽。这种机制也被称为快捷键。注意快捷键是窗口部件的子对象并且当窗口部件被销毁的时候销毁。<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html">QAccel</A><EM>不是</EM>窗口部件,并且在它的父对象中没有任何可见的效果。 

<P>我们定义两个快捷键。我们希望在Enter键被按下的时候调用fire()槽,在Ctrl+Q键被按下的时候,应用程序退出。因为Enter有时又被称为Return,并且有时键盘中<EM>两个</EM>键都有,所以我们让这两个键都调用fire()。 

<P><PRE>        accel-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html#connectItem">connectItem</A>( accel-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qaccel.html#insertItem">insertItem</A>( CTRL+Key_Q ),
                            qApp, SLOT(<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qapplication.html#quit">quit</A>()) );
</PRE>
<P>并且之后我们设置Ctrl+Q和Alt+Q做同样的事情。一些人通常使用Ctrl+Q更多一些(并且无论如何它显示了如果做到它)。 
<P>CTRL、Key_Enter、Key_Return和Key_Q都是Qt提供的常量。它们实际上就是Qt::Key_Enter等等,但是实际上所有的类都继承了<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qt.html">Qt</A>这个命名空间类。 
<P><PRE>        <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qgridlayout.html">QGridLayout</A> *grid = new <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qgridlayout.html">QGridLayout</A>( this, 2, 2, 10 );
    <A name=x2373></A>    grid-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qgridlayout.html#addWidget">addWidget</A>( quit, 0, 0 );
        grid-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qgridlayout.html#addWidget">addWidget</A>( box, 1, 1 );
    <A name=x2374></A>    grid-&gt;<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qgridlayout.html#setColStretch">setColStretch</A>( 1, 10 );
</PRE>
<P>我们放置<TT>box</TT>(<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A>),不是CannonField,在右下的单元格中。 

<P>
<H2>行为 </H2><A name=2></A>
<P>现在当你按下Enter的时候,加农炮就会发射。你也可以用鼠标来确定加农炮的角度。障碍物会使你在玩游戏的时候获得更多一点的挑战。我们还会在CannnonField周围看到一个好看的框架。 

<P>(请看<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/tutorial1-07.html#compiling">编译</A>来学习如何创建一个makefile和连编应用程序。) 

<P>
<H2>练习 </H2><A name=3></A>
<P>写一个空间入侵者的游戏。 
<P>(这个练习首先被<A href="mailto:igorr@ifi.uio.no">Igor Rafienko</A>作出来了。你可以<A 
href="http://www.stud.ifi.uio.no/~igorr/download.html">下载他的游戏</A>。) 
<P>新的练习是:写一个突围游戏。 
<P>最后的劝告:现在向前进,创造<EM>编程艺术的杰作</EM>! 
<P>
<P>[<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/tutorial1-13.html">上一章</A>] 
[<A 
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/tutorial1-01.html">第一章</A>] 
[<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/tutorial.html">教程一主页</A>] 
<P><!-- eof -->
<P>
<ADDRESS>
<HR>

<DIV align=center>
<TABLE cellSpacing=0 width="100%" border=0>
  <TBODY>
  <TR>
    <TD>Copyright &copy; 2002 <A href="http://www.trolltech.com/">Trolltech</A> 
    <TD><A href="http://www.trolltech.com/trademarks.html">Trademarks</A> 
    <TD><A 
      href="http://www.qtopia.org.cn/doc/qiliang.net/qt/zh_CN.html">译者:Cavendish</A> 

    <TD align=right>
      <DIV align=right>Qt 
3.0.5版</DIV></TR></TBODY></TABLE></DIV></ADDRESS></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -