<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook V3.1-Based Variant V1.0//EN" [
 <!ENTITY kdevelop "<application>kdevelop</application>">
 <!ENTITY % addindex "IGNORE">
 <![ %addindex; [ <!ENTITY docindex SYSTEM "docindex.docbook"> ]]>
]>
<book lang="zh-CN">
<bookinfo>
<title>KDE应用程序教程
</title>
<subtitle>基于KDevelop集成开发环境的KDE应用程序教程手册</subtitle>
<authorgroup>
<author>
<surname>Ralf Nolden </surname>
<affiliation>
	  <orgname>KDevelop小组</orgname>
<address><email><ulink url="mailto:Ralf.Nolden@post.rwth-aachen.de">&lt;Ralf.Nolden@post.rwth-aachen.de&gt;</ulink></email></address>
</affiliation>
      </author>
      <othercredit role="translator">
	<surname> 译者：李宋琛</surname>
	<affiliation>
<address><email><ulink url="mailto:leesongchen@263.net">leesongchen@263.net</ulink></email></address>
</affiliation>
</othercredit>
</authorgroup>
<date>版本0.1，1999年6月21日。译于1999年8月。</date>
<releaseinfo><!-- information about this particular version --></releaseinfo>
<abstract>
<para>KDE应用程序教程手册用实例教你如何生成KDE应用程序以及如何建立Qt库附带的教程例子。该手册是
KDevelop集成开发环境的一部分，因此它受GPL的保护。参见<link linkend="Copyright">版权</link>以获得进一步的信息。</para>
<para>KDE</para><!-- Merge this with the previous paragraph; it comes from <META NAME="description" CONTENT="..."> --></abstract>
<keywordset>
<keyword>KDE</keyword>
</keywordset>

</bookinfo>

<chapter id="index-0">
<title>简介</title>

<para>当KDE逐渐成为Unix的标准桌面系统时，越来越多的开发者希望能够利用其提供的卓越的应用程序接口，
开发出带有KDE风格的应用程序。因此，KDevelop宗旨就是为开发者提供一个集成开发环境，使他们在
把焦点集中于KDE时，能够快速地创建和拓展应有程序。由于初学者在开始时有不少困难，这本手册解
释了KDE应用程序的某些方面。它通过例子讲述了如何使用 KDevelop生成 Qt自带的例程以及如何生成
KDE应用程序。</para>

<para>因此，在下一章我们将会向你解释如何把现存的，完整的应用程序转换成KDevelop的一个项目；然后，
我们将来到包含在Qt中的在线文档，看一看如何使用Qt库。</para>

<para>你会初次了解到Qt的工作方式以及如何使用这些类；我们的学习从Qt开始，因为KDE是建立在Qt库之上
的而且在KDE应用程序中也有广泛地应用。</para>

<para>然后，我们会教你如何用KDevelop的应用程序向导生成一个最小的KDE应用程序。从这个最小的框架开
始，我们将生成一个使用KDE库而且可以运行的KDE式例程序，然后再详细解释KDE应用程序的各个部分。</para>

<para>KDevelop小组希望你通过这本手册学会如何使用KDE和Qt，同时也希望你能为KDE作出贡献。</para>

<sect1 id="index-1">
<title>预备知识</title>

<para>为了能够理解例子中的代码，阅读本手册需要一些基本的C++编程知识。再者，你应该首先阅读<ulink url="../index.html">KDevelop用户手册</ulink>和<ulink url="../programming/index.html">KDevelop编程手册</ulink>，知道基本概念和基本操作。</para>
</sect1>
</chapter>

<chapter id="index-2">
<title>准备开始</title>

<para>准备开始——此意即你必须首先让KDevelop能够正常的工作。确信你可以通过“帮助”菜单或文档树
访问Qt的在线文档。在文档的第一页，你会看到它包括“Tutorials（教程）”和“Examples（例子）”
的链接。在“教程”中，你可以通过十四步的介绍学习如何用Qt库建立应用程序。另一方面，“例子”
包含了一系列的例程，它们为如何使用这些类提供了参考。现在，如果你是一个完全的初学者，你应该
欣赏Qt的思想——它提供了：
<itemizedlist>
<listitem>
<para>基本的应用程序类（<literal remap="tt">QApplication</literal>）</para>
</listitem>
<listitem>
<para>图形用户界面的widget库</para>
</listitem>
<listitem>
<para>一系列的图形，文件和数据处理等辅助库</para>
</listitem>
<listitem>
<para>用于对象通信的signal-slot机制</para>
</listitem>
<listitem>
<para>使用事件循环和虚方法来实现事件控制</para>
</listitem>
</itemizedlist>
</para>

<para>如果目前你对这些一无所知，你应该读一读<ulink url="../programming/index-2.html#ss2.1">KDevelop编程手册</ulink>，它详细描述了Qt应用程序的
基本概念。同时，你也会了解到Qt和KDE应用程序的区别。不过，这些区别在教程这样的初级阶段表现
得并不明显。</para>

<para>既然首先学习Qt是学习编写KDE程序的良好开端，我们就用教程中的程序来生成一个项目。</para>

<para>为此，从菜单条中选择“项目”—“新建”。在应用程序向导中选择项目类型。对于Qt程序，就选择
“Qt—普通”，但是我们要使用迷你KDE项目来建立例子。原因很简单：Qt的教程并没有包含多少代
码，如果在向导中选择Qt应用程序，我们就得为生成一个“真正”的例子而作很大的改变。</para>

<para>而迷你KDE应用程序不但包括一个空的主窗口，还包括必要的库和头文件，它恰好符合我们的要求而有
不用作太大的改动。</para>

<para>在下一向导页中，我们需要输入有关项目的信息。在那儿，我们可以不用管诸如迷你图标，主图标，文
档等KDE专用的附加选项。我们只需要输入与教程相关的信息就可以了。教程在安排上是一步接一步的，
所以我们从<literal remap="tt">MyWidget</literal>开始，在第四章中会用到这个类，这样到时候就不用为此操心了。我们从教
程的第一步开始，因而把‘1’作为项目号，以后各步依此增加就可以了。</para>

<para>然后，填上你的名字，电子邮件地址，项目目录等等。完成以后进入下一页。在此插入文件头。你可以
自己选一个文件或者就用所给的例子。第四页也一样，为源文件选择文件头。在最后一页中，选择‘生成’
就可以创建项目了。如果该按钮不可用，你就得从第一页开始检查有没有必需的信息没有填。</para>

<para>如果一切正常，在向导的信息窗口中的最后一行会显示“READY“。然后按”关闭“结束。</para>

<para>看一看左边的树状视图，你发现已经有一个"MyWidget"类——这是因为我们选择它作为应用程序名。
再者，在类视图的“全局”中选择“函数”，你可以看到应用程序已经包含了<literal remap="tt">main()</literal>函数，程序
就是从这里开始执行。</para>

<para>现在整个应用程序已经设置好了。你可以选择“执行”或“连编”，可是我们要生成教程中的应用呀？
所以在下一步中，我们会继续并添加代码，然后生成教程中的例子。</para>
</chapter>

<chapter id="qt">
<title>建立Qt教程</title>

<sect1 id="hello-world">
<title>第一步：Hello World!</title>

<para>正如在上一章讲到的，我们创建了一个叫<literal remap="tt">MyWidget</literal>的项目——现在，如果看一下Qt文档教程的第
一页，你会发现第一个应用程序只包含<literal remap="tt">main()</literal>函数。因此，我们只需要修改项目的<literal remap="tt">main()</literal>
函数就可以使教程的第一步运行了。</para>

<para>要访问<literal remap="tt">main()</literal>函数，从“CV”中选择“全局”文件夹，其中又包含了一个“函数”子文件夹，
所有的非类函数都罗列在这里。在右边的“C/C++文件“窗口中会打开<literal remap="tt">main.cpp</literal>，而光标已经
被设置在了<literal remap="tt">main()</literal>的的第一行。</para>

<sect2 id="index-3">
<title>首先改什么</title>

<para>我们可以从现有的代码开始把它改成需要的样子——但是有更容易的办法。用鼠标或按住Shift用下箭头
选择整个<literal remap="tt">main()</literal>。然后再从”编辑“中选择”剪切“或者按DEL键删除所选的代码。在清除整个main
函数后，我们就可以从头开始建立我们的第一个教程。</para>
</sect2>

<sect2 id="index-4">
<title>输入教程代码</title>

<para>现在，输入教程中的代码。你可以先仔细地读一遍并试着记住那一行有那些代码。然后，在依次读完教程
的叙述以后，你就可以把它当作例子完成这个教程。</para>

<para>还有更简单的办法：从文档浏览器中选择整个<literal remap="tt">main()</literal>函数并按一下工具条上的”复制“图标。另外，
你也可以使用右键的弹出式菜单或者用”编辑“菜单。这些都会将内容复制到剪贴板中，切换回源代码
窗口以后再选择”粘贴“。（可以用工具条，右键的弹出式菜单或者”编辑“菜单）</para>

<para>最后，在<literal remap="tt">main()</literal>函数外加入相应的头文件：
<screen>#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;
</screen>
</para>

<para>好了！第一个教程应用的源代码已经准备完毕。</para>
</sect2>

<sect2 id="hello-world-0">
<title>建立Hello World!</title>

<para>要建立第一个教程，从”建立“菜单中选择“连编”或者按工具条上相应的按钮。另外，你也可以选择
“执行”，它会在建立成功以后执行应用程序。</para>

<para>如果在建立过程中由于错误而停了下来，请相信这是由于你的失误而与教程无关！太打击了吧，我才
刚刚决定写KDE/Qt程序呢！但是，你却可以因此来熟悉使用KDevelop。为了发现错误所在，你有两个
选择：或者点击输出窗口中相应的错误信息，它会把你带到出错所在的行，或者按F4键；另外，你还
可以在“查看”菜单中选择“下一个错误”。</para>
</sect2>

<sect2 id="index-5">
<title>练习</title>

<para>你可能会问“练习？太简单了吧，我不需要做什么练习！”，但是请相信，以后的例子会变得越来越复
杂的。虽然这个程序是最简单的例子，但是它们越复杂你就需要花费越多的精力去思考才能搞懂这些教
程中的代码。而且做一做练习也可以使你学会如何在实践中使用KDevelop和它的各项特征。</para>

<para>为了在第一个教程中学到更多的知识，你应该试着按照下面所述的提示改变代码，然后看一看这些变化
是如何影响程序行为的：
<orderedlist><listitem>
<para>把按钮变成QLabel</para>
</listitem>
<listitem>
<para>用<literal remap="tt">setText()</literal>代替在构造函数中直接为按钮设置文本</para>
</listitem>
<listitem>
<para>用<literal remap="tt">QPushButton::resize ( const QSize & s )</literal>代替
直接设置宽和高。创建一个<literal remap="tt">QSize</literal>的实例，其中包含size</para>
</listitem>
<listitem>
<para>改变这些大小，看一看哪个是宽，哪个是高</para>
</listitem>
</orderedlist>
</para>
</sect2>
</sect1>

<sect1 id="index-6">
<title>第二步和第三步：拓展</title>

<para>教程的第二步和第三步是第一步的展开，你可以从中学到signal和slot以及在widget间的父子关系。</para>

<para>为什么要学这些呢？signal和slot是Qt库和其它widget库之间最大的区别。当你涉及到需要实现在各个
对象之间通信时，它会显著地缩短工作时间。如果发生了错误是不会导致严重后果的，即使错误的连接
也不会导致“segmentation fault”这样的错误。这就是Qt的力量，而正因为其灵活性，许多的KDE/Qt
开发者都不想失去它。因此，明白signal/slot机制是创建任何KDE/Qt程序的要点。</para>

<para>另一件需要注意的事是，按钮调用<literal remap="tt">quit()</literal>来结束<literal remap="tt">QApplication</literal>实例。你在使用<literal remap="tt">QApplication</literal>
的KDE装饰物或<literal remap="tt">KApplication</literal>时会再次遇到<literal remap="tt">quit()</literal></para>
</sect1>

<sect1 id="widget">
<title>编写你自己的Widget</title>

<para>在成功的更改并拓展<literal remap="tt">main()</literal>函数后，你将生成一个新的widget——一个唯一的你在第四步中可以
创建的wideget。事实上，这个类已经由应用程序向导生成了，所以并不需要添加很多的代码——你只
需要把在第四课<literal remap="tt">main.cpp</literal>文件中的代码插入到<literal remap="tt">MyWidget</literal>类的头文件和实现文件就可以了。
幸运的是，实际上你只用把实现部分添加到构造函数中。</para>

<para>从类视图中选择要访问的构造函数。这会自动把你带到需要添加代码的实现部分。</para>

<para>要注意包括<literal remap="tt">qfont.h&gt;——<literal remap="tt">QFont</literal>只用在<literal remap="tt">MyWidget</literal>的构造函数中。因此，在<literal remap="tt">mywidget.cpp&gt;
的顶部添加<literal remap="tt">&num;include &lt;qfont.h&gt;</literal>
要运行程序，只要按一下“执行”就可以了。它会在自动保存后编译更改后的代码。</literal></literal></para>
    </sect1>

<sect1 id="widget-0">
<title>扩展Widget类</title>

<para>第五课的目标是扩展widget类。因而，你会学到有关虚拟函数的知识。在这里<literal remap="tt">resizeEvent()</literal>被重
写。另一个需要重点学习的是（除了如何扩展类）Qt使用虚函数来处理用户事件，而把事件本身作为
参数。因此，你必须熟悉以下的Qt类：
<itemizedlist>
<listitem>
<para>QEvent</para>
</listitem>
<listitem>
<para>QChildEvent</para>
</listitem>
<listitem>
<para>QCloseEvent</para>
</listitem>
<listitem>
<para>QFocusEvent</para>
</listitem>
<listitem>
<para>QKeyEvent</para>
</listitem>
<listitem>
<para>QMouseEvent</para>
</listitem>
<listitem>
<para>QMoveEvent</para>
</listitem>
<listitem>
<para>QPaintEvent</para>
</listitem>
<listitem>
<para>QResizeEvent</para>
</listitem>
<listitem>
<para>QTimerEvent</para>
</listitem>
</itemizedlist>
</para>

<para>无论何时写自己的widget，特别是应用程序的可视区域，你都得自己重写那些需要处理的widget事件方
法，以替代缺省的实现。例如：</para>

<para><literal remap="tt">virtual void mousePressEvent ( QMouseEvent *)</literal>处理鼠标事件。在实现时，你必须在函数头中
输入一个参数名，大多数程序员用<literal remap="tt">event</literal>或者干脆用<literal remap="tt">e</literal>作为参数名。</para>

<para>然后你就可以处理事件参数了。对<literal remap="tt">QMouseEvent</literal>而言，你可以知道引发该事件的按钮是左键，中键
或者右键。</para>
    </sect1>

<sect1 id="index-7">
<title>添加新类</title>

<para>在第六课里，你需要为教程程序添加一个新类。一般你可能会想“我只需要创建一个头文件和一个实现
文件就可以了”——但是KDevelop使你做起来更轻松。当添加一个类时，你应该总使用类生成器。它会
为你做所有的工作而你只需要添加必需的代码。</para>

<para>要使用类生成器添加类，选择“项目”——“新建类”，在打开的对话框中输入你需要的值。首先要输
入类名。教程用<literal remap="tt">LCDRange</literal>，所以首先输入这个名字。然后是基类。基类就是新类所要继承的类。
看一下教程（Qt 1.42），这是<literal remap="tt">QWidget</literal>。由于大部分的GUI类都是从QWidget继承，类生成器简化
了这个步奏。不输入基类类名而在“附加选项”部分选上“QWidget的子类”这会自动在头文件中加入<literal remap="tt">Q&lowbar;OBJECT</literal>宏，使用slot和signal必需此宏。（见在第七章）</para>

<para>因为文件名是自动输入的，你不必去管它。唯一需要提醒的是添加文档。为类添加描述性的文档总是一
个好的风格，特别是类名<literal remap="tt">LCDRange</literal>并不告诉你该widget的用途。</para>
    </sect1>

<sect1 id="index-8">
<title>第七到十四步</title>

<para>在教程的剩余各步中，你会学到所有必需的知识——添加所需的类并做各种改动。</para>

<para>在每一次更改后，你都应该重新建立并检查错误。运行一下应用程序，看看它是如何执行的；另外，你应
该玩一玩KDevelop“建立”的参数—运行应用程序时加上命令行参数如—geometry，用工具窗口中的KDbg
进行调试。然后你就能够进行Qt例子，它们在下一章中讨论。</para>
    </sect1>
  </chapter>

<chapter id="copyright">
<title>版权 </title>

<para><screen>
KDevelop 版权属于 KDevelop小组1998，1999
该程序是自由软件；你可以在遵守自由软件基金会所公布的
GNU通用公共许可证的前提下发布或（和）修该此程序。许
可证版本不应低于2.0。

发布该程序的目的是希望它对你有用，但是*没有任何担保*；
无论是明确的，还是隐含的，包括但不限於可销售和适合特
定用途的隐含保证。请参看 GNU通用公共许可证了解更多的
细节。

你应该与该程序一同收到一份GNU通用公共许可证；如果没有，
请写信到一下地址索取：
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</screen>
</para>
</chapter>
<![ %addindex; [ &docindex; ]]>
</book>
<!--
Local Variables:
mode: sgml
sgml-omittag: nil
sgml-shorttag: t
sgml-general-insert-case: lower
End:
-->
