目录

  • 1 学习情境一、媒体播放器
    • 1.1 项目背景和工作目标
    • 1.2 工作任务
    • 1.3 工作任务一:需求分析
    • 1.4 工作任务二:系统设计
    • 1.5 工作任务三:编码实现
    • 1.6 工作任务四:系统集成与测试
    • 1.7 工作任务五:项目总结
  • 2 学习情境二、Qt连连看游戏
    • 2.1 项目背景和工作目标
    • 2.2 工作任务
    • 2.3 工作任务一:需求分析
    • 2.4 工作任务二:系统设计
    • 2.5 工作任务三:编码实现
    • 2.6 工作任务四:系统集成与测试
    • 2.7 工作任务五:项目总结
  • 3 学习情境三、毕业电子相册
    • 3.1 项目背景和工作目标
    • 3.2 工作任务
    • 3.3 工作任务一:需求分析
    • 3.4 工作任务二:系统设计
    • 3.5 工作任务三:编码实现
    • 3.6 工作任务四:系统集成与测试
    • 3.7 工作任务五:项目总结
  • 4 第一章 单片机概述
    • 4.1 单片机简介
    • 4.2 单片机特点
    • 4.3 单片机应用领域
    • 4.4 单片机发展趋势
    • 4.5 MCS-51系列与AT89S5x系列单片机
    • 4.6 其他嵌入式处理器简介
  • 5 AT89S51单片机的片内硬件结构
    • 5.1 AT89S51单片机的硬件组成
    • 5.2 AT89S51单片机的引脚
    • 5.3 AT89S51的CPU
    • 5.4 AT89S51单片机存储器的结构
    • 5.5 AT89S51单片机的并行I/O端口
    • 5.6 时钟电路和时序
    • 5.7 复位操作和复位电路
    • 5.8 看门狗定时器的使用
  • 6 C51语言编程基础与KEIL uVision3开发平台
    • 6.1 C51编程语言概述
    • 6.2 C51语言程序设计基础
    • 6.3 C51语言的函数
    • 6.4 Keil uVision3环境下的C51语言程序开发
  • 7 虚拟仿真平台Porteus的使用(自学)
  • 8 单片机开关检测、键盘输入与显示接口设计
    • 8.1 单片机控制LED显示
    • 8.2 开关状态检测
    • 8.3 单片机控制LED数码管显示
  • 9 中断系统
    • 9.1 中断技术概述
    • 9.2 中断系统结构
    • 9.3 中断允许中断优先级的控制
    • 9.4 响应中断请求的条件
    • 9.5 外部中断响应时间
    • 9.6 外部中断触发方式选择
    • 9.7 中断请求的撤消
    • 9.8 中断函数
    • 9.9 中断系统应用举例
  • 10 定时/计数器
    • 10.1 定时/计数器结构
    • 10.2 定时计数器的4种工作方式
    • 10.3 对外部输入的计数信号的要求
    • 10.4 定时/计数器的编程和应用
  • 11 串行口的工作原理及应用
    • 11.1 串行口结构
    • 11.2 串行口的4种工作方式
    • 11.3 多机通信
    • 11.4 波特率的制定方法
    • 11.5 串行口应用设计实例
  • 12 单片机系统的扩展
    • 12.1 系统并行扩展技术
    • 12.2 外部数据存储器的并行扩展
    • 12.3 EEPROM存储器的并行扩展
  • 13 AT89S52单片机与DAC、ADC的接口
    • 13.1 单片机扩展DAC 概述
    • 13.2 单片机扩展并行8位DAC0832芯片的设计
    • 13.3 单片机扩展ADC概述
    • 13.4 单片机并行扩展8位A/D转换器ADC0809
  • 14 课程导学
    • 14.1 课程介绍
    • 14.2 课程对接职业技能证书标准
    • 14.3 实训过程演示
  • 15 基础性实验
    • 15.1 实验1 实验平台搭建
    • 15.2 实验2 设备状态指示灯的控制——LED灯的控制
    • 15.3 实验3 八路病房呼叫系统——数码管应用
    • 15.4 实验4 三相交流电故障检测系统——外部中断的应用
    • 15.5 实验5 模拟报警声控制——定时器的应用
    • 15.6 实验6 单片机双机通信——串口通信的应用
  • 16 综合性实验
    • 16.1 实验1 倒车警示器
    • 16.2 实验2 心形多路花样彩灯
    • 16.3 实验3 简易计算器
    • 16.4 实验4 多功能电子时钟
    • 16.5 实验5 自动化生产线产品计数打包系统
    • 16.6 实验6 简易数字电压表
    • 16.7 实验7 光控小夜灯
  • 17 创新性实验
    • 17.1 实验1 带倒计时功能的交通信号灯
    • 17.2 实验2 基于串口通信的LED点阵广告屏
    • 17.3 实验3 带温度显示的电子万年历
  • 18 考试题库
    • 18.1 电信5-8班 电信12班考试题库
    • 18.2 电信3、4班考试题库
工作任务三:编码实现


                                          1.5工作任务三:编码实现

1.5.1任务描述

在软件编码阶段,开发者根据《软件系统详细设计报告》中对数据结构、算法分析和模块实现等方面的设计要求,开始具体的编写程序工作,分别实现各模块的功能,从而实现对目标系统的功能、性能、接口、界面等方面的要求。

 

1.5.2任务目的

本任务的目的是使用C++语言,把模块过程性描述翻译为用C++语言书写的源程序(源代码)。提高学生交流沟通协作的能力,提高学生互评能力、欣赏别人的品质。

1.5.3知识点准备

零、Qt与Qt Creator介绍

一、 Qt与Qt Creator简介

Qt 是一个跨平台应用程序和 UI 开发框架。使用 Qt 您只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操作系统部署这些应用程序。

Qt Creator 是全新的跨平台 Qt IDE,可单独使用,也可与 Qt 库和开发工具组成 一套完整的SDK. 其中包括:高级 C++ 代码编辑器,项目和生成管理工具,集成的上下文相关的帮助系统,图形化调试器,代码管理和浏览工具。

二、 Qt功能与特性

直观的 C++ 类库:模块化 Qt C++ 类库提供一套丰富的应用程序生成块 (block),包含了构建高级跨平台应用程序所需的全部功能。具有直观,易学、易用,生成好理解、易维护的代码等特点。

跨桌面和嵌入式操作系统的移植性:使用 Qt,您只需一次性开发应用程序,就可跨不同桌面和嵌入式操作系统进行部署,而无须重新编写源代码,可以说Qt无处不在(Qt Everywhere) 。


  • 使用单一的源代码库定位多个操作系统;


  • 通过重新利用代码可将代码跨设备进行部署;


  • 无须考虑平台,可重新分配开发资源;


  • 代码不受担忧平台更改影响的长远考虑 


  • 使开发人员专注于构建软件的核心价值,而不是维护 API

具有跨平台 IDE 的集成开发工具:Qt Creator 是专为满足 Qt 开发人员需求而量身定制的跨平台集成开发环境 (IDE)。Qt Creator 可在 Windows、Linux/X11 和 Mac OS X 桌面操作系统上运行,供开发人员针对多个桌面和移动设备平台创建应用程序。

在嵌入式系统上的高运行时间性能,占用资源少。

三、 Qt Creator功能和特性

复杂代码编辑器:Qt Creator 的高级代码编辑器支持编辑 C++ 和 QML (JavaScript)、上下文相关帮助、代码完成功能、本机代码转化及其他功能。

版本控制:Qt Creator 汇集了最流行的版本控制系统,包括 Git、Subversion、Perforce、CVS 和 Mercurial。

集成用户界面设计器:Qt Creator 提供了两个集成的可视化编辑器:用于通过 Qt widget 生成用户界面的 Qt Designer,以及用于通过 QML 语言开发动态用户界面的 Qt Quick Designer*。

项目和编译管理 :无论是导入现有项目还是创建一个全新项目,Qt Creator 都能生成所有必要的文件。包括对 cross-qmake 和 Cmake 的支持。

桌面和移动平台:Qt Creator 支持在桌面系统和移动设备中编译和运行 Qt 应用程序。通过编译设置您可以在目标平台之间快速切换。

Qt 模拟器:Qt模拟器是诺基亚 QtSDK 的一部分,可在与目标移动设备相似的环境中对移动设备的 Qt 应用程序进行测试。

四、 Qt的历史


  • 1996Qt 上市


  • Qt     已成为数以万计商业和开源应用程序的基础


  • Qt     的软件授权机制具有经受市场检验的双重授权(开源与商业)模式


  • Qt     Software 的前身为 Trolltech(奇趣科技)。 Trolltech (奇趣科技)始创于1994


  • Trolltech     (奇趣科技)于20086月被 Nokia 收购,加速了其跨平台开发战略

五、 Qt所支持的平台


  1. 嵌入式 Linux Embedded Linux

Qt for Embedded Linux® 是用于嵌入式 Linux 所支持设备的领先应用程序架构。您可以使用 Qt 创建具有独特用户体验的具备高效内存效率的设备和应用程序。Qt 可以在任何支持 Linux 的平台上运行。Qt 的直观API,让您只须少数几行代码便可以更短的时间实现更高端的功能。

特点:1. 用于Linux 的紧凑的视窗系统;2. 用于广泛的应用程序处理器的开发;3. 移植桌面代码至嵌入式平台,或通过重新编译,反之亦然;4. 编译移除不常使用的组件与功能;5. 利用系统资源并实现本地化性能;6. 开发嵌入式设备犹如开发桌面系统一样轻松简单。

Qt 除了提供所有 工具 以及 API 与 类库 ,(如 WebKit ) 外,Qt for Embedded Linux 还提供用于最优化嵌入式开发环境的主要组件。

紧凑高效的视窗系统 (QWS):Qt 构建在标准的 API 上,应用于嵌入式 Linux 设备,并带有自己的紧凑视窗系统。基于 Qt 的应用程序直接写入Linux 帧缓冲,解除了您对 X11 视窗系统的需求。具有减少内存消耗,占位更小,可利用硬件加速图形的优势,可编译移除不常使用的组件与功能等特点。

虚拟帧缓冲 (QVFb):Qt for Embedded Linux 提供一个虚拟帧缓冲器,可以采用点对点逐像素匹配物理设备显示。具有真实的测试构架,在桌面系统上嵌入式测试,模拟物理设备显示的宽度、高度与色深等特点。

进程间通讯 (IPC) :IPC (进程间通讯)可以创建丰富的多应用程序用户体验。定义进程间通讯的两个主要概念即:信道与消息。可以进程监听并向信道发送消息,任何时候只要监听到一个进程便可创建信道。

扩展的字体格式:Qt 支持嵌入式 Linux 上的多种字体格式,包括:TrueType®, Postscript®Type1 与 Qt 预呈现字体。Qt 扩展了Unicode 支持,包括:构建时自动数据抽取和运行时自动更新。另外Qt还提供定制字体格式的插件,允许在运行时轻松添加新字体引擎。应用程序间的字体共享功能可以提高内存效率。

基本要求:

开发环境:Linux  内核 2.4 或更高;GCC 版本 3.3 或更高;用于 MIPS® GCC 版本 3.4. 或更高。

占用存储空间:存储空间取决于配置,压缩后: 1.7 –4.1 MB,未压缩: 3.6 – 9.0 MB 。

硬件平台:易于载入任何支持带 C++ 编译器和帧缓冲器驱动 Linux 的处理器。支持 ARM®, x86®, MIPS®, PowerPC® 。

2.Mac平台

Qt 包括一套集成的开发工具,可加快在 Mac 平台上的开发。在编写 Qt 时,并不需要去设想底层处理器的数字表示法、字节序或架构。要在 Apple 平台上支持 Intel 硬件,Qt 客户只需重新编辑其应用程序即可。

3.Windows平台

使用 Qt,只需一次性构建应用程序,无须重新编写源代码,便可跨多个 Windows 操作系统的版本进行部署。Qt 应用程序支持 Windows Vista、Server 2003、XP、NT4、Me/98 和 Windows CE。

4.Linux/X11平台

Qt 包括一套集成的开发工具,可加快在 X11 平台上的开发。Qt由于是  KDE 桌面环境的基础,在各个Linux 社区人尽皆知。几乎 KDE 中的所有功能都是基于Qt 开发的, 而且 Qt 是全球社区成员用来开发 成千上万的开源 KDE 应用程序的基础。

5.Windows CE/Mobile

Qt 是用 C++ 开发的应用程序和用户界面框架。通过直观的API,您可以使用 Qt 为大量的设备编写功能丰富的高性能应用程序。Qt 包括一套丰富的工具集与直观的API,意味着只须少数几行代码便可以更短的时间实现更高端的功能。

主要特点:1.硬件依存性极小;2.支持多数现有的 Windows CE 配置;3. 对于自定义的硬件配置亦轻松构建;4. 移植桌面代码至嵌入式平台,或通过重新编译,反之亦然;5. 编译移除不常使用的组件与功能;6. 利用系统资源并实现高性能;7. 开发嵌入式设备尤如开发桌面系统一样轻松简单。

Qt 除了提供所有 工具 以及 API 与 类库 外,Qt for Windows CE 还提供用于最优化嵌入式开发环境的附加功能。

本地化和可定制的外观:Qt 在使用时,可以支持 Windows Mobile 和 Windows CE 两种样式。 在运行时,Qt 应用程序将检测使用哪一种样式。 采用 Qt 样式表单,您只需要花费用于传统 UI 风格的少许时间和代码行,便可以轻松定制您的应用程序外观。特点:基于HTML 层叠式样式表 (CSS);适用于全部 widget;任何熟悉 CSS 技术的人员都可以定义复杂的样式。

先进的文本布局引擎:Qt for Windows CE 支持 TrueType® 和点阵字体。同时 Qt 还支持扩展的 Unicode 和从右至左的书写语言。Qt 的富文本引擎增加了新的功能用于复杂的文本布局,包括制表和路径追踪,以及环绕图形的文本。

基本要求:

开发环境: Microsoft® VisualStudio® 2005 (Standard Edition) 或更高ActivePerl  。

占用存储空间:紧凑配置 – 4.8 MB,全配置 – 8.4 MB。

操作系统:Windows CE 5 或更高,Windows Mobile 5 或更高。

硬件平台:支持 ARM®, x86®,(在 SH4® 和 MIPS® 上编译) 。

6. 塞班平台(Symbian)

Qt 通过和S60 框架的集成为 Symbian 平台提供了支持。在最新版的Qt SDK 1.1中我们可以直接生成可以在塞班设备上运行的sis文件。

7.MeeGo平台 (Maemo 6 现更名为 MeeGo)

Qt 是一个功能全面的应用程序和用户界面框架,用来开发Maemo 应用程序,也可跨各主要设备和桌面操作系统部署这些程序且无需重新编写源代码的。 如果您在多数情况下开发适用于 Symbian、Maemo 或 MeeGo 平台的应用程序,可以使用免费 LGPL 授权方式的 Qt。

Qt 将为诺基亚设备运行 MeeGo (Harmattan) 提供依托,并可为所有即将推出的 MeeGo 设备中的应用程序开发提供 API,为 Qt 开发人员提供了更多平台。不久,MeeGo 设备就会完全支持 (X11) Qt 。

六、 Qt类库

模块化 Qt C++ 类库提供一套丰富的应用程序生成块 (block),包含了生成高级跨平台应用程序所需的全部功能。

1.先进的图形用户界面(GUI):Qt为您在桌面与嵌入式平台上开发先进的GUI应用程序,带来所有需要的功能。Qt使用所支持平台的本地化图形API,充分利用系统资源并给予应用程序本地化的界面。

从按钮和对话框到树形视图与表格都具有完整的控件(窗体)

自动缩放,字体、语言与屏幕定位识别布局引擎

支持抗锯齿、矢量变形以及可缩放矢量图形 (SVG)

具有样式API和窗体样式表,可完全自定义用户界面

支持嵌入式设备的硬件加速图形和多重显示功能

2.基于OpenGL ®与OpenGL ®Es的3D图形:OpenGL® 是一个标准的图形库,用于构建跨平台和支持硬件加速的高性能可视化应用程序。虽然OpenGL完美支持3D图形,但却不支持创建应用程序用户界面。Qt通过与OpenGL 的紧密集成解决了这一难题。

在您的应用程序中轻松加入3D图形

在嵌入式Linux 与Windows CE 平台上使用OpenGL ES和OpenGL绘画引擎

利用系统资源实现最佳图形性能

支持Windows 平台上的Direct3D®

3.多线程:多线程编程是一个执行资源密集型操作而不会冻结应用程序用户界面的有效典范。Qt的跨平台多线程功能简化了并行编程,另外它附加的同步功能可以更加轻松地利用多核架构。

管理线程、数据和对象更加轻松

基于Qt的信号与槽,实现跨线程类型安全的对象间通讯

高端API可以编译多线程程序而无须使用底端基元

4.嵌入式设备的紧凑视窗系统:Qt构建在标准的 API基础上,用于具有轻量级window系统的嵌入式 Linux 设备。基于 Qt的应用程序直接写入 Linux 帧缓冲,解除了您对 X11 视窗系统的需求。

减少内存消耗,内存占用更小

可以编译移除不常使用的组件与功能

可以利用硬件加速图形

在桌面系统上的虚拟帧缓冲可用于嵌入式开发与调试

5.对象间通讯:在开发用户图形界面中,一个常见的、重复发生系统崩溃与问题的症结根源是如何在不同组件之间进行通信。对于该问题,Qt 的解决方案是信号与槽机制,即执行Observer设计模式。我们可以简单理解为当特殊事件发生的时候,信号就被发出了,一个插槽就是一个函数,被称作特定信号的响应。

信号与槽机制是类型安全的(type safe)

任意信号都可以连接任意或多个插槽,或跨多个线程

简化真正的组件编程

6.2D图形:Qt给您提供一个功能强大的2D图形画布,用以管理和集成大量的图形元素。

高精度可视化大量元素

将窗体互动嵌入至图形场景中

支持缩放、旋转、动画与透视变换

7.多媒体框架:Qt使用 Phonon多媒体框架为众多的多媒体格式提供跨桌面与嵌入式操作系统的回放功能。Phonon可以轻松将音频与视频回放功能加入到Qt应用程序当中,并且在每个目标平台上提取多媒体格式与框架。

以平台独立的方式提供多媒体内容

从本地文件读取媒体或读取网络上的流媒体

提取Mac上的 QuickTime® ,Windows 上的DirectShow® 以及 Linux 上的Gstreamer

8.WebKit集成:Qt WebKit集成,即Qt集成了WebKit功能,WebKit是KDE项目下基于KHTML的开放源web浏览器引擎。目前 Apple®,Google™ 与Nokia等公司使用QtWebKit集成。

将web与本地内容和服务整合在单一的富应用程序当中

快速创建整合实时web内容与服务的应用程序

使用集成在本地代码中的 HTML 与Java Script

完全控制跨平台的浏览器环境

9.网络连接:Qt 让您网络编程更简单,并支持跨平台网络编程。

完整的客户/服务器插口提取

支持 HTTP,FTP,DNS 与异步 HTTP 1.1

无论HTML 和XML或图象与媒体文件,它都可以存取所有类型的数据

10.XML:Qt 为XML 文件以及SAX 和 DOM 协议的C++实现,提供了一个流媒体文件读写器。同时 Qt 还包含了 XQuery – 一个简单的类似 SQL的查询语言,用于解析XML文件来选择和聚合所需要的XML元素,并且将它们转换成XML输出或其它格式的输出。

仅需少数几行代码便可实现先进的 XML 查询

完全支持 XQuery 1.0 和 XPath 2.0

在您自己的应用程序中从XML查询、抽取和转换数据

11.脚本引擎:Qt 包含一个完全集成 ECMA 标准的脚本引擎。 QtScript 提供 QObject 集成,把 Qt的信号与槽机制整合成脚本,并且实现了C++ 与脚本的集成。

基于ECMA 标准的脚本语言 (ECMAScript 3是JavaScript 1.5的基础)

为简化的对象间通讯使用Qt的信号与槽机制

开创新的契机将脚本与您的Qt应用程序相集成

12.数据库:Qt 帮助您将数据库与您的Qt应用程序无缝集成。Qt支持所有主要的数据驱动,并可让您将SQL发送到数据库服务器,或者让 Qt SQL类自动生成 SQL 查询。

支持所有主要的数据库驱动

以多种视图或数据识别表单方式显示数据

七、 Qt Quick介绍

Qt Quick是在Qt 4.7中被引进的一项技术。Qt Quick 是一种高级用户界面技术,开发人员和设计人员可用它协同创建动画触摸式用户界面和应用程序。它由三部分构成:1.QML:像 JavaScript 一样的声明式语言;2. Qt Creator:在 Qt IDE中的直观工具;3. Qt Declarative:强大的 C++ 模块。

1.主要组成:

QML基于 JavaScript 的直观语言  :QML 是一种简便易用的语言,开发人员与用户界面设计人员无需任何 C++ 知识,即可用其描绘出用户界面的外观和功能。

面向开发人员和设计人员的共享工具:Qt Creator IDE 2.1 版将集成一套开发人员与用户界面设计人员可共享,用以创建和实施 QtQuick 项目的通用工具。

通过 C++ 推动 QML 应用程序:在 Qt 库中的全新Declarative 模块支持生成动态可定制的用户界面,以及通过 C++ 拓展 QML 应用程序。

2.功能特点:

快速开发动画式流畅多变的用户界面:通过直观的 QML 语言和一套丰富的 QML Elements——UI 和行为生成块——您可以快速创建出令人印象深刻的用户界面,比您想象的还要快。

无需 C++ 知识:如果您具有 JavaScript 的经验或掌握基本的网络技术 (如 HTML 和 CSS),您就可以通过QML 取得非常不错的成果。

瞄准数以百万计的触摸屏设备:使用 Qt Quick,您可以为数以百万计的 Symbian 和 MeeGo 设备生成应用程序,或为各种类型的触摸屏消费类电子设备创建用户界面。

3.应用领域:

汽车信息娱乐系统 UI:CybercomGroup 的用户界面设计人员与开发人员尝试使用Qt Quick 为其汽车信息娱乐平台设计 UI——并取得了令人满意的结果。

社交媒体电视:mixd.tv 使用 Qt Quick 为其跨平台网络电视应用程序创建 UI,其用户可以通过社交媒体频道访问和共享在线视频的内容。

联网汽车:Qt 的认证合作伙伴 Digia 很快学会了 Qt Quick 并用其创建出了包括导航、电话、游戏和音乐功能的高级汽车 UI。

八、 Qt授权


  • Qt Commercial Developer     License

The Qt Commercial DeveloperLicense is the correct license to use for the development of proprietary and/orcommercial software with Qt where you do not want to share any source code.

You must purchase a Qt CommercialDeveloper License from us or from one of our authorized resellers before youstart developing commercial software as you are not permitted to begin yourdevelopment with an open source licensed Qt version and convert to thecommercially license version at a later . The Qt Commercial Developer Licenseincludes a restriction that prevents the combining of code developed with theQt GNU LGPL v. 2.1 or GNU GPL v. 3.0 license versions with commerciallylicensed Qt code.


  • Qt GNU LGPL v. 2.1 Version

This version is available fordevelopment of proprietary and commercial applications in accordance with theterms and conditions of the GNU Lesser General Public License version 2.1.

Support services are availableseparately for purchase.


  • Qt GNU GPL v. 3.0 Version

This version is freely availablefor the development of open source software governed by the GNU General PublicLicense version  3.0 (“GPL”).

Support services are availableseparately for purchase.

LicenseComparison Chart

                                                               


 

Commercial

 
 

LGPL

 
 

GPL

 
 

License  cost

 
 

License  fee charged

 
 

No  license fee

 
 

No  license fee

 
 

Must  provide source code changes to Qt

 
 

No,  modifications can be closed

 
 

Source  code must be provided

 
 

Source  code must be provided

 
 

Can create  proprietary applications

 
 

Yes –  No source code must be disclosed

 
 

Yes, in  accordance with the LGPL v. 2.1 terms

 
 

No,  applications are subject to the GPL and source code must be made available

 
 

Updates  provided

 
 

Yes,  immediate notice sent to those with a valid support and update agreement

 
 

Yes,  made available

 
 

Yes,  made available

 
 

Support

 
 

Yes, to  those with a valid support and update agreement

 
 

Not  included but available separately for purchase

 
 

Not  included but available separately for purchase

 
 

Charge  for Runtimes

 
 

Yes,  for some embedded uses

 
 

No

 
 

No

 

结语:对于Qt 和Qt Creator有了大致的了解了,已经迫不及待想马上开始Qt的学习了吧!那么从我们的Qt Creator系列教程开始吧,让你快速进入Qt的开发行列之中!

一、Qt Creator的安装和hello world程序的编写

主要讲述windows下的Qt Creator下载、安装和最简单程序的编写,然后在附录里又讲解了两种其他的编写程序的方法。在linux下Qt Creator下载、安装及程序的编写基本与此相同。

1.1  Qt简介

Qt 是一个跨平台的 C++ 图形用户界面库,由挪威 TrollTech 公司出品,目前包括Qt基于 Framebuffer Qt Embedded,快速开发工具 Qt Designer,国际化工具 Qt Linguist 等部分 Qt 支持所有 Unix 系统,当然也包括 Linux,还支持 WinNT/Win2kWin95/98 平台。

Qt 具有下列优点:


  1. 优良的跨平台特性:

Qt支持下列操作系统: Microsoft Windows 95/98, Microsoft Windows NT, Linux, Solaris, SunOS,HP-UX, Digital UNIX (OSF/1,Tru64), Irix, FreeBSD, BSD/OS, SCO, AIX, OS390,QNX 等等。


  1. 面向对象

Qt 的良好封装机制使得 Qt 的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。 Qt 提供了一种称为 signals/slots 的安全类型来替代 callback,这使得各个元件 之间的协同工作变得十分简单。


  1. 丰富的 API

Qt 包括多达 250 个以上的C++ 类,还替供基于模板的 collections,serialization, file, I/O device, directory management, date/time 类。甚至还包括正则表达式的处理功能。


  1. 支持 2D/3D 图形渲染,支持 OpenGL


  2. 大量的开发文档


  3. XML 支持

1.2  Qt Creator的下载和安装

1. 下载

首先到Qt的官方网站上下载Qt Creator,这里我们下载windows版的。

   

 

Qt  SDK: 完整的开发环境

 
 

Qt SDK IconQt SDK 在一个单独的安装程序内包括了使用 Qt 构建跨平台应用程序所需的工具。

  

下载地址:http://qt.nokia.com/downloads 如下图我们下载:Download Qt SDK for Windows*

选择离线安装:(1.7GB)  

http://get.qt.nokia.com/qtsdk/Qt_SDK_Win_offline_v1_1_2_en.exe

2. 安装

下载完成后,直接安装即可,安装过程中按默认设置即可。

 

1.3  编写最简单的程序

1、新建工程

(1)运行Qt Creator,首先弹出的是欢迎界面,这里可以打开其自带的各种演示程序。

(2)我们用File->New菜单来新建工程。

(3)这里我们选择Qt4 Gui Application。

(4)下面输入工程名和要保存到的文件夹路径。我们这里的工程名为helloworld。

(5)这时软件自动添加基本的头文件,因为这个程序我们不需要其他的功能,所以直接点击Next。

(6)我们将base class选为QDialog对话框类。然后点击Next。

(7)点击Finish,完成工程的建立。

2、运行程序

圆角矩形标注: RUN按钮(1)我们可以看见工程中的所有文件都出现在列表中了。我们可以直接按下下面的绿色的run按钮或者按下Ctrl+R快捷键运行程序。

(2)程序运行会出现空白的对话框,如下图。

3、编写程序

(1)我们双击文件列表的dialog.ui文件,便出现了下面所示的图形界面编辑界面。

(2)我们在右边的器件栏里找到Label标签器件

(3)按着鼠标左键将其拖到设计窗口上,如下图。

(4)双击它,并将其内容改为helloworld。

(5)在右下角的属性栏里将字体大小由9改为15。

(6)拖动标签一角的蓝点,将全部文字显示出来。

(7)再次按下运行按钮,便会出现helloworld。

到这里helloworld程序便完成了。      

1.4  运行执行程序的说明

Qt Creator编译的程序,在其工程文件夹下会有一个debug文件夹,其中有程序的.exe可执行文件。但Qt Creator默认是用动态链接的,就是可执行程序在运行时需要相应的.dll文件。我们点击生成的.exe文件,首先可能显示“没有找到mingwm10.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。”表示缺少mingwm10.dll文件。

    解决这个问题我们可以将相应的.dll文件放到系统中。在Qt Creator的安装目录的qt文件下的bin文件夹下(我安装在了D盘,所以路径是D:\Qt\2009.04\qt\bin),可以找到所有的相关.dll文件。

(1)方法一:在这里找到mingwm10.dll文件,将其复制到C:\WINDOWS\system文件夹下即可。下面再提示缺少什么dll文件,都像这样解决就可以了。

(2)方法二:将这些dll文件都与.exe文件放到同一个文件夹下。不过这样每个.exe文件都要放一次。

(3)方法三:将D:\Qt\2009.04\qt\bin加入系统Path环境变量。右击我的电脑->属性->高级->环境变量->在系统变量列表中找到Path,将路径加入其中即可。

附1:用纯源码编写。

1.新建空的Qt4工程。

2.工程名为helloworld,并选择工程保存路径(提示:路径中不能有中文)。

3.在新建好的工程中添加文件。右击工程文件夹,弹出的菜单中选择Add New。

4.选择普通文件。点击Ok。

5.文件名为main.cpp,点击Next进入下一步。

6.这里自动将这个文件添加到了新建的工程中。保持默认设置,点击完成。

7.在main.cpp文件中添加代码。

8.这时点击运行,程序执行了,但看不到效果,因为程序里什么也没做。我们点击信息框右上角的红色方块,停止程序运行。

9.我们再更改代码。添加一个对话框对象。

10.运行效果如下。

11.我们更改代码如下,在对话框上添加一个标签对象,并显示hello world。

12.运行效果如下。

附2:利用ui文件。

1.建立新的空工程,这里的工程名为hello,建立好工程后,添加新文件。这里添加Qt Designer Form。

2.选择一个对话框做模板。

3.你可以更改文件名,我们这里使用默认设置。

4.在新建好的框口上添加一个标签,并更改文本为hello world。

5.在工程文件夹上点击右键,弹出的菜单中选择第一项编译工程。

6.因为还没有写主函数,所以现在编译文件会出现错误,不过没关系,因为我们只是想编译一下ui文件。

7.点击这个图标,去掉弹出的菜单中第二项前的对勾,显示隐藏的文件。这时你就能看到ui文件对应的头文件了。

而如果去掉菜单中的第一项前的对勾,列表中的文件就会分类显示,如图

8.ui文件对应的.h文件默认为ui_dialog.h(例如form.ui对应ui_form.h)。

其中是设计器设计的窗口的对应代码。我们这里的.h文件是最简单的,其类名为Ui_Dialog,可以看到其中有我们添加的标签对象。

9.在这个类里有一个setupUi函数,我们就是利用这个函数来使用设计好的窗口的。

10.我们添加main.cpp文件,并更改内容如下。

其中ui->setupUi(dd);一句就是将设计的窗口应用到新建的窗口对象上。

11.这时运行程序,效果如下。

1.5 小结

在这本章中,一共讲述了二种最简单的helloworld程序的方法,一种是应用设计器向导,一种是全部手写代码,其实他们是等效的。因为我们已经看到,就算是设计器生成,其实也是写了一个对应的ui.h文件,只不过这个文件是自动生成的,不用我们自己写而已。

二、Qt Creator编写多窗口程序

实现功能:

      程序开始出现一个对话框,按下按钮后便能进入主窗口,如果直接关闭这个对话框,便不能进入主窗口,整个程序也将退出。当进入主窗口后,我们按下按钮,会弹出一个对话框,无论如何关闭这个对话框,都会回到主窗口。

实现原理:

      程序里我们先建立一个主工程,作为主界面,然后再建立一个对话框类,将其加入工程中,然后在程序中调用自己新建的对话框类来实现多窗口。

实现过程:

1.首先新建Qt4 Gui Application工程,工程名为nGui,Base class选为QWidget。建立好后工程文件列表如下图。

http://j.imagehost.org/0035/1_29.jpg

2.新建对话框类,如下图,在新建中,选择Qt Designer Form Class。

http://j.imagehost.org/0932/2_2.jpg

3.选择Dialog without Buttons。

http://j.imagehost.org/0332/3_16.jpg

4.类名设为myDlg。

http://j.imagehost.org/0246/4_4.jpg

5.点击Finish完成。注意这里已经默认将其加入到了我们刚建的工程中了。

http://j.imagehost.org/0039/5_5.jpg

6.如下图,在mydlg.ui中拖入一个Push Button,将其上的文本改为进入主窗口,在其属性窗口中将其objectName改为enterBtn,在下面的Signals and slots editor中进行信号和槽的关联,其中,Sender设为enterBtn,Signal设为clicked(),Receive设为myDlg,Slot设为accept()。这样就实现了单击这个按钮使这个对话框关闭并发出Accepted信号的功能。下面我们将利用这个信号。

http://j.imagehost.org/0446/6_10.jpg

7.修改主函数main.cpp,如下:

#include <QtGui/QApplication>

#include “widget.h”

#include “mydlg.h”      //加入头文件

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    Widget w;

   myDlg my1;      //建立自己新建的类的对象my1

   if(my1.exec()==QDialog::Accepted)    //利用Accepted信号判断enterBtn是否被按下

    {

       w.show();         //如果被按下,显示主窗口

        return a.exec();      //程序一直执行,直到主窗口关闭

   }

    else return 0;     //如果没被按下,则不会进入主窗口,整个程序结束运行

}

主函数必须这么写,才能完成所要的功能。

如果主函数写成下面这样:

#include <QtGui/QApplication>

#include “widget.h”

#include “mydlg.h”

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

        myDlg my1;

    if(my1.exec()==QDialog::Accepted)

    {

Widget w;

        w.show();

      }

   return a.exec();

}

这样,因为w是在if语句里定义的,所以当if语句执行完后它就无效了。这样导致的后果就是,按下enterBtn后,主界面窗口一闪就没了。如果此时对程序改动了,再次点击运行时,就会出现error: collect2: ld returned 1 exit status的错误。这是因为虽然主窗口没有显示,但它只是隐藏了,程序并没有结束,而是在后台运行。所以这时改动程序,再运行时便会出错。你可以按下调试栏上面的红色Stop停止按钮来停止程序运行。你也可以在windows任务管理器的进程中将该进程结束,而后再次运行就没问题了,当然先关闭Qt Creator,而后再重新打开,这样也能解决问题。

如果把程序改为这样:

#include <QtGui/QApplication>

#include “widget.h”

#include “mydlg.h”

int main(int argc, char *argv[])

{

    QApplication a(argc,argv);

       myDlg my1;

        Widget w;

    if(my1.exec()==QDialog::Accepted)

    {  

        w.show();

      }

   return a.exec();

}

这样虽然解决了上面主窗口一闪而过的问题,但是,如果在my1对话框出现的时候不点enterBtn,而是直接关闭对话框,那么此时整个程序应该结束执行,但是事实是这样的吗?如果你此时对程序进行了改动,再次按下run按钮,你会发现又出现了error:collect2: ld returned 1 exit status的错误,这说明程序并没有结束,我们可以打开windows任务管理器,可以看到我们的程序仍在执行。

      因为return a.exec();一句表示只要主窗口界面不退出,那么程序就会一直执行。所以只有用第一种方法,将该语句也放到if语句中,而在else语句中用else return 0; 这样如果enterBtn没有被按下,那么程序就会结束执行了。

        到这里,我们就实现了一个界面结束执行,然后弹出另一个界面的程序。下面我们在主窗口上加一个按钮,按下该按钮,弹出一个对话框,但这个对话框关闭,不会使主窗口关闭。

8.如下图,在主窗口加入按钮,显示文本为弹出一个对话框,在其上点击鼠标右键,在弹出的菜单中选择go to slot。

http://j.imagehost.org/0238/7_11.jpg

9.我们选择单击事件clicked()。

http://j.imagehost.org/0642/8_7.jpg

10.我们在弹出的槽函数中添加一句:

     my2.show();

   my2为我们新建对话框类的另一个对象,但是my2我们还没有定义,所以在widget.h文件中添加相应代码,如下,先加入头文件,再加入my2的定义语句,这里我们将其放到private里,因为一般的函数都放在public里,而变量都放在private里。

#ifndef WIDGET_H

#define WIDGET_H

#include <QtGui/QWidget>

#include “mydlg.h”    //包含头文件

namespace Ui

{

class Widget;

}

class Widget : public QWidget

{

Q_OBJECT

public:

Widget(QWidget *parent = 0);

~Widget();

private:

Ui::Widget *ui;

myDlg my2;      //对my2进行定义

private slots:

void on_pushButton_clicked();

};

#endif // WIDGET_H

到这里,再运行程序,便能完成我们实验要求的功能了。整个程序里,我们用两种方法实现了信号和槽函数的关联,第一个按钮我们直接在设计器中实现其关联;第二个按钮我们自己写了槽函数语句,其实图形的设计与直接写代码效果是一样的。

      这个程序里我们实现了两类窗口打开的方式,一个是自身消失而后打开另一个窗口,一个是打开另一个窗口而自身不消失。可以看到他们实现的方法是不同的。

三、Qt Creator登录对话框

实现功能:

在弹出对话框中填写用户名和密码,按下登录按钮,如果用户名和密码均正确则进入主窗口,如果有错则弹出警告对话框。

实现原理:

通过上节的多窗口原理实现由登录对话框进入主窗口,而用户名和密码可以用if语句进行判断。

实现过程:

1.先新建Qt4 Gui Application工程,工程名为mainWidget,选用QWidget作为Base class,这样便建立了主窗口。文件列表如下:

http://j.imagehost.org/0067/1_22.jpg

2.然后新建一个Qt Designer Form Class类,类名为loginDlg,选用Dialog without Buttons,将其加入上面的工程中。文件列表如下:

http://j.imagehost.org/0997/2_16.jpg

3.在logindlg.ui中设计下面的界面:行输入框为Line Edit。其中用户名后面的输入框在属性中设置其object Name为usrLineEdit,密码后面的输入框为pwdLineEdit,登录按钮为loginBtn,退出按钮为exitBtn。

http://j.imagehost.org/0112/3_10.jpg

4.将exitBtn的单击后效果设为退出程序,关联如下:

http://j.imagehost.org/0927/4_7.jpg

5.右击登录按钮选择go to slot,再选择clicked(),然后进入其单击事件的槽函数,写入一句

    void loginDlg::on_loginBtn_clicked()

{

    accept();

}

6.改写main.cpp:

#include <QtGui/QApplication>

#include “widget.h”

#include “logindlg.h”

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    Widget w;

    loginDlglogin;

    if(login.exec()==QDialog::Accepted)

    {

       w.show();

       return a.exec();

    }

    else return 0;

}

7.这时执行程序,可实现按下登录按钮进入主窗口,按下退出按钮退出程序。

8.添加用户名密码判断功能。将登陆按钮的槽函数改为:

void loginDlg::on_loginBtn_clicked()

{

if(m_ui->usrLineEdit->text()==tr(“qt”)&&m_ui->pwdLineEdit->text()==tr(“123456″))

//判断用户名和密码是否正确

accept();

else{

QMessageBox::warning(this,tr(“Warning”),tr(“user name or password error!”),QMessageBox::Yes);

//如果不正确,弹出警告对话框

}

}

并在logindlg.cpp中加入#include<QtGui>的头文件。如果不加这个头文件,QMessageBox类不可用。

(说明:由于版本原因,现在的程序默认生成的ui类对象可能是ui,而不是m_ui,请到loginDlg.h中查看。)

9.这时再执行程序,输入用户名为qt,密码为123456,按登录按钮便能进入主窗口了,如果输入错了,就会弹出警告对话框。

http://j.imagehost.org/0330/5_7.jpg

如果输入错误,便会弹出警告提示框:

http://j.imagehost.org/0131/6_8.jpg

10.在logindlg.cpp的loginDlg类构造函数里,添上初始化语句,使密码显示为小黑点。

loginDlg::loginDlg(QWidget *parent):

QDialog(parent),

m_ui(new Ui::loginDlg)

{

m_ui->setupUi(this);

m_ui->pwdLineEdit->setEchoMode(QLineEdit::Password);

}

效果如下:

http://j.imagehost.org/0329/7_10.jpg

11.如果输入如下图中的用户名,在用户名前不小心加上了一些空格,结果程序按错误的用户名对待了。

http://j.imagehost.org/0134/8_1.jpg

我们可以更改if判断语句,使这样的输入也算正确。

void loginDlg::on_loginBtn_clicked()

{

if(m_ui->usrLineEdit->text().trimmed()==tr(“qt”)&&m_ui->pwdLineEdit->text()==tr(“123456″))

accept();

else{

QMessageBox::warning(this,tr(“Warning”),tr(“user name or password error!”),QMessageBox::Yes);

}

}

加入的这个函数的作用就是移除字符串开头和结尾的空白字符。

12.最后,如果输入错误了,重新回到登录对话框时,我们希望可以使用户名和密码框清空并且光标自动跳转到用户名输入框,最终的登录按钮的单击事件的槽函数如下:

void loginDlg::on_loginBtn_clicked()

{

if(m_ui->usrLineEdit->text().trimmed()==tr(“qt”)&&m_ui->pwdLineEdit->text()==tr(“123456″))

//判断用户名和密码是否正确

accept();

else{

QMessageBox::warning(this,tr(“Warning”),tr(“user name or password error!”),QMessageBox::Yes);

//如果不正确,弹出警告对话框

m_ui->usrLineEdit->clear();//清空用户名输入框

m_ui->pwdLineEdit->clear();//清空密码输入框

m_ui->usrLineEdit->setFocus();//将光标转到用户名输入框

}

}

最终的loginDlg.cpp文件如下图:

http://j.imagehost.org/0738/9_8.jpg

四、Qt Creator添加菜单图标

在下面的几节,我们讲述Qt的MainWindow主窗口部件。这一节只讲述怎样在其上的菜单栏里添加菜单和图标。

1.新建Qt4 Gui Application工程,将工程命名为MainWindow,其他选项默认即可。

生成的窗口界面如下图。其中最上面的为菜单栏。

http://j.imagehost.org/0964/1_23.jpg

2.我们在Type Here那里双击,并输入文件(&F)”,这样便可将其文件菜单的快捷键设为Alt+F。(注意括号最好用英文半角输入,这样看着美观)

http://j.imagehost.org/0089/2_5.jpg

3.输入完按下Enter键确认即可,然后在子菜单中加入新建(&N)”,确定后,效果如下图。

http://j.imagehost.org/0893/3_1.jpg

4.我们在下面的动作编辑窗口可以看到新加的新建菜单。

http://j.imagehost.org/0301/4_7.jpg

5.双击这一条,可打开它的编辑对话框。我们看到Icon项,这里可以更改新建菜单的图标。

http://j.imagehost.org/0199/5_7.jpg

6.我们点击后面的号,进入资源选择器,但现在这里面是空的。所以下面我们需要给该工程添加外部资源。

http://j.imagehost.org/0011/6_3.jpg

7.添加资源有两种方法。一种是直接添加系统提供的资源文件,然后选择所需图标。另一种是自己写资源文件。我们主要介绍第一种。新建Qt Resources file,将它命名为menu。其他默认。

http://j.imagehost.org/0904/7_9.jpg

8.添加完后如下图。可以看到添加的文件为menu.qrc。

http://j.imagehost.org/0205/8_11.jpg

9.我们最好先在工程文件夹里新建一个文件夹,如images,然后将需要的图标文件放到其中。

http://j.imagehost.org/0600/9_5.jpg

10.在QtCreator的menu.qrc文件中,我们点击Add下拉框,选择Add Prefix。我们可以将生成的/new/prefix前缀改为其他名字,如/File。

http://j.imagehost.org/0010/10_1.jpg

11.然后再选择Add下拉框,选择Add Files。再弹出的对话框中,我们到新建的images文件夹下,将里面的图标文件全部添加过来。

http://j.imagehost.org/0316/11_2.jpg

12.添加完成后,我们在Qt Creator的File菜单里选择SaveAll选项,保存所做的更改。(注意:一定要先保存刚才的qrc文件,不然在资源管理器中可能看不见自己添加的资源!

http://j.imagehost.org/0206/12_2.jpg

13.这时再打开资源选择器,可以看到我们的图标都在这里了。(注意:如果不显示,可以按一下上面的Reload按钮)

http://j.imagehost.org/0117/13_3.jpg

14.我们将new.png作为新建菜单的图标,然后点击Shortcut,并按下Crtl+N,便能将Crtl+N作为新建菜单的快捷键。

http://j.imagehost.org/0417/14_9.jpg

15.这时打开文件菜单,可以看到新建菜单已经有图标了。

http://j.imagehost.org/0320/15_9.jpg

运行程序后效果如下。

http://j.imagehost.org/0126/16.jpg

16.我们在工程文件夹下查看建立的menu.qrc文件,可以用写字板将它打开。

http://j.imagehost.org/0030/17_1.jpg

其具体内容如下。

http://j.imagehost.org/0920/18_6.jpg

附:第二种添加资源文件的方法。

1.首先右击工程文件夹,在弹出的菜单中选择Add New,添加新文件。也可以用File中的添加新文件。

http://j.imagehost.org/0731/19_3.jpg

2.我们选择文本文件。

http://j.imagehost.org/0629/20_3.jpg

3.将文件名设置为menu.qrc。

http://j.imagehost.org/0931/21.jpg

4.添加好文件后将其内容修改如下。可以看到就是用第一种方法生成的menu.qrc文件的内容。

http://j.imagehost.org/0329/22_15.jpg

5.保存文件后,在资源管理器中可以看到添加的图标文件。

五、Qt Creator布局管理器的使用

上篇讲解了如何在Qt Creator中添加资源文件,并且为菜单添加了图标。这次我们先对那个界面进行一些完善,然后讲解一些布局管理器的知识。

首先对菜单进行完善。

1.我们在上一次的基础上再加入一些常用菜单。

文件的子菜单如下图。中间的分割线可以点击Add Separator添加。

http://j.imagehost.org/0531/1_33.jpg

编辑子菜单的内容如下。

http://j.imagehost.org/0216/2_5.jpg

帮助子菜单的内容如下。

http://j.imagehost.org/0622/3_5.jpg

2.我们在动作编辑器中对各个菜单的属性进行设置。

如下图。

http://j.imagehost.org/0919/4_1.jpg

3.我们拖动新建菜单的图标,将其放到工具栏里。

拖动新建菜单的图标。

http://j.imagehost.org/0723/5_2.jpg

将其放到菜单栏下面的工具栏里。

http://j.imagehost.org/0430/6_14.jpg

4.我们再添加其他几个图标。使用Append Separator可以添加分割线。

http://j.imagehost.org/0236/7_5.jpg

5.最终效果如下。如果需要删除图标,可以在图标上点击右键选择Remove action即可。

下面简述一下布局管理器。

(这里主要以垂直布局管理器进行讲解,其他类型管理器用法与之相同,其效果可自己验证。)

1.在左边的器件栏里拖入三个PushButton和一个Vertical Layout(垂直布局管理器)到中心面板。如下图。

http://j.imagehost.org/0926/9_13.jpg

2.将这三个按钮放入垂直布局管理器,效果如下。可以看到按钮垂直方向排列,并且宽度可以改变,但高度没有改变。

http://j.imagehost.org/0743/10_8.jpg

3.我们将布局管理器整体选中,按下上面工具栏的Break Layout按钮,便可取消布局管理器。(我们当然也可以先将按钮移出,再按下Delete键将布局管理器删除。)

http://j.imagehost.org/0641/11_13.jpg

4.下面我们改用分裂器部件(QSplitter)。

先将三个按钮同时选中,再按下上面工具栏的Lay Out Vertically in Splitter(垂直分裂器)。

http://j.imagehost.org/0943/12_4.jpg

效果如下图。可以看到按钮的大小可以随之改动。这也就是分裂器和布局管理器的分别。

http://j.imagehost.org/0750/13_13.jpg

5.其实布局管理器不但能控制器件的布局,还有个很重要的用途是,它能使器件的大小随着窗口大小的改变而改变。

我们先在主窗口的中心拖入一个文本编辑器Text Edit。

http://j.imagehost.org/0150/14_6.jpg

这时直接运行程序,效果如下。可以看到它的大小和位置不会随着窗口改变。

http://j.imagehost.org/0038/15_6.jpg

下面我们选中主窗口部件,然后在空白处点击鼠标右键,选择Layout->Lay Out in a Grid,使整个主窗口的中心区处于网格布局管理器中。

http://j.imagehost.org/0357/16_7.jpg

可以看到,这时文本编辑器已经占据了整个主窗口的中心区。

http://j.imagehost.org/0254/17_3.jpg

运行一下程序,可以看到无论怎样拉伸窗口,文本编辑框的大小都会随之改变。

http://j.imagehost.org/0556/18_4.jpg

我们在这里一共讲述了三种使用布局管理器的方法,一种是去器件栏添加,一种是用工具栏的快捷图标,还有一种是使用鼠标右键的选项。

 

1.5.4任务实现

推荐歌曲功能的实现过程如下:

1.客户端发送请求给服务器端,格式为:

     

 

块大小

 
 

服务类型’M’

 
 

用户名

 

2.服务器端得到服务类型为’M’,调用recommendsend(QStringusername)函数。该函数负责向用户推荐歌曲列表,方法就是前面给出的方法,它的具体实现的主要代码是:

QStrings="selectusernamefromuserwhereusername!='"+username+"'";

    query.exec(s);

    intsum=query.size();

    QString*name=newQString[sum];

    double*ratio=newdouble[sum];

    int*count=newint[sum];

    int*samecount=newint[sum];

    inti;

    for(i=0;i<sum;i++)

    {

        query.next();

        name[i]=query.value(0).toString();

    }

    for(i=0;i<sum;i++)

    {

        s="selectcount(*)from"+name[i];

        query.exec(s);

        query.next();

        count[i]=query.value(0).toInt();

        s="selectcount(*)from"+name[i]+"whereIDin(selectIDfrom"+username+")";

        query.exec(s);

        query.next();

        samecount[i]=query.value(0).toInt();

        ratio[i]=samecount[i]/count[i];

    }

    intmaxratioid=0;

    for(i=1;i<sum;i++)

    {

        if(ratio[i]>ratio[maxratioid])

            maxratioid=i;

    }

    s="selectIDfrom"+name[maxratioid]+"whereIDnotin(selectIDfrom"+username+")";

    intn;

    query.exec(s);

    n=query.size();

    int*songid=newint[n];

    QString*songurl=newQString[n];

    QString*songname=newQString[n];

    QString*singer=newQString[n];

    QString*lrcurl=newQString[n];

    for(i=0;i<n;i++)

    {

       query.next();

       songid[i]=query.value(0).toInt();

    }

    for(i=0;i<n;i++)

    {

        s="select*fromsongwhereid="+tr("%1").arg(songid[i]);

        query.exec(s);

        query.next();

        songurl[i]=query.value(1).toString();

        songname[i]=query.value(2).toString();

        singer[i]=query.value(3).toString();

        lrcurl[i]=query.value(5).toString();

}

得出结果后,返回给客户端,格式为:

           

 

块大小

 
 

服务类型’M’

 
 

结果个数

 
 

第一首歌曲信息

 
 

…….

 
 

最后一首歌曲信息

 

因为这些歌曲都是用户没有选为喜欢的,所以不需要像搜索功能一样,最后接上是否喜欢数组。

3.客户端接收到信息后,新建一个窗口显示信息,当用户点击其中的一首歌曲时,播放该歌曲。至此实现了歌曲推荐的功能。

3.3.8歌词显示

由于QT中没有歌词显示的插件或函数,所以在本程序中歌词的显示是通过对文件、字符串等的综合处理实现的。

歌词显示模块涉及到的函数有:lrcshow(qint64time)、replyFinished(QNetworkReply*reply)、deletelrc()、getlrc()和readlrc()。涉及到的全局变量有:intlrclinecount;intlrctimecount;Qstringrc_text[100];lrctimelrc_time[100];boolopened,其中lrctime结构体的定义为:
structrctime
{
    longtime;
    intstringid;
};
getlrc()函数就一句:manager->get(QNetworkRequest(QUrl(current.songlrc)));功能是向网络发送一个下载该歌词文件的请求,当连接完成,可以下载时,会产生一个信号,直接调用replyFinished(QNetworkReply*reply)函数,该函数将文件保存在程序的目录下,文件名为歌词URL中的名称。接着使用readlrc()函数对歌词文件进行读取,在该函数中对lrclinecount(要显示的歌词的行数)、lrctimecount(要进行判断的歌词时间个数)、rc_text[](存放每一行的字符串)、lrc_time[](存放时间以及该时间对应的字符串在rc_text[]中所处的位置)等进行赋值,最后由lrcshow(qint64time)根据播放的进度时间进行歌词显示。当播放的歌曲对象变化后,使用deletelrc()函数,将该歌词文件从硬盘中删除。
歌词显示的核心是读取歌词文件,也就是readlrc()函数,它的主要代码如下:
if(current.songlrc!=NULL)
        {
            QFileInfofileInfo(QUrl(current.songlrc).path());
            QStringfileName=fileInfo.fileName();
            QFilefile(fileName);
                 if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
                {
                     opened=false;
                     return;
                 }
                 opened=true;
                 QTextStreamin(&file);
                 QStringline=in.readLine();
            inti=0;
            intj=0;
            intk=1;
            while(!line.isNull())
            {
                if(line.length()>0&&line.at(0)=='['&&line.at(1)>='0'&&line.at(1)<='9')
                {
  lrc_time[i].time=(line.at(1).toAscii()-48)*600000+(line.at(2).toAscii()-48)*60000+(line.at(4).toAscii()-48)*10000+(line.at(5).toAscii()-48)*1000+(line.at(7).toAscii()-48)*100+(line.at(8).toAscii()-48)*10;
                    lrc_time[i].stringid=j;
                    i++;
                    while(line.length()>k*10&&line.at(k*10)=='[')
                    {
                        lrc_time[i].time=(line.at(k*10+1).toAscii()-48)*600000+(line.at(k*10+2).toAscii()-48)*60000+(line.at(k*10+4).toAscii()-48)*10000+(line.at(k*10+5).toAscii()-48)*1000+(line.at(k*10+7).toAscii()-48)*100+(line.at(k*10+8).toAscii()-48)*10;
                        lrc_time[i].stringid=j;
                        i++;
                        k++;
                    }
                    if(line.length()<=k*10)
                    {
                        lrc_text[j]="";
                    }
                    else{
                        lrc_text[j]=line.mid(k*10);
                        }
                 j++;
                }
                k=1;
                line=in.readLine();
            }
            lrclinecount=j;
            lrctimecount=i;
       file.close();
            lrctimetemp;
            for(i=0;i<lrctimecount;i++)
            {
                  for(j=n-1;j>i;j--)
                   if(lrc_time[j].time<lrc_time[j-1].time)
                      {
                         temp=lrc_time[j];
                         lrc_time[j]=lrc_time[j-1];
                         lrc_time[j-1]=temp;
                      }
            }
    }
    
    
 
3.4服务器端

由于服务器端只是对用户提出的要求进行一些服务,所以界面只是一个退出按钮。服务器端最主要的是定义ClientSocket类,它是继承的QtcpSocket类,对它里面的一些函数进行了重定义,实现了来一个客户端请求就新建一个ClientSocket类来实现用户的需要。

 (4)测试计划

如表14所示:

                             

 

假设电脑玩家记忆的数字

 
 

普通玩家第一次输入

 
 

普通玩家第二次输入

 
 

普通玩家第三次输入

 
 

普通玩家第四次输入

 
 

3

 
 

最佳方案:5

 

系统提示:猜大了

 
 

最佳方案:2

 

系统提示:猜小了

 
 

最佳方案:3

 

系统提示:你真棒,正确

 
 

 





14