530 likes | 747 Views
移动应用软件开发技术 第四讲: Meego 应用开发基础. 《 移动应用软件开发技术 》 课程建设小组 北京大学 二零一一年 *致谢:感谢 Intel 对本课程项目的支持. 课程内容. Qt 介绍 Qt 安装 基于 QT 的 Hello World 示例程序 Qt 中主要类的介绍 Qt 的信号槽机制 Qt 中主要控件介绍. Qt 介绍. Qt 是跨平台的应用程序和 UI 框架,包括 跨平台类库 集成开发环境 跨平台 IDE 一次性开发可在不同桌面和嵌入式操作系统部署. Qt 特征一. 面向对象 Qt 具有模块设计和注重软件构件或元素的可重用性的特点
E N D
移动应用软件开发技术第四讲:Meego应用开发基础移动应用软件开发技术第四讲:Meego应用开发基础 《移动应用软件开发技术》课程建设小组 北京大学 二零一一年 *致谢:感谢Intel对本课程项目的支持
课程内容 • Qt介绍 • Qt安装 • 基于QT的Hello World示例程序 • Qt中主要类的介绍 • Qt的信号槽机制 • Qt中主要控件介绍
Qt介绍 • Qt是跨平台的应用程序和UI框架,包括 • 跨平台类库 • 集成开发环境 • 跨平台IDE • 一次性开发可在不同桌面和嵌入式操作系统部署
Qt特征一 • 面向对象 • Qt具有模块设计和注重软件构件或元素的可重用性的特点 • 构件支持 • Qt提供信号signal和槽slot的概念,支持对象之间在彼此不知道对方的情况下合作,使得Qt适合构件编程 • 友好的联机帮助 • Qt提供了大量的联机参考文件
Qt特征二 • 便利性 • Qt是跨平台的GUI工具包,对编程者隐藏了处理不同窗口系统时的潜在问题 • 国际化 • Qt为本地化应用提供了完全的支持,所有用户界面文本都可以基于消息翻译表被翻译成各国语言
Qt特征三 • 丰富的API函数 • Qt为开发者提供了大量的函数 • 可用户化外观 • Qt支持主题,基于Qt的应用程序能够在Windows外观,Motif外观以及其他一些用户外观主题之间切换 • 完整的组件工具 • Qt编程的基本模块叫做组件,Qt含有用来创建专业外观用户界面需要的所有组建
Qt介绍 • Who uses Qt? • Write code once to target multiple platforms • Create amazing user experience • Do more with less and faster • Blend web and native code in a single application
Qt SDK • Qt SDK
Qt中主要的类介绍 • QObject QObject类是所有能够处理signal,slot和事件的Qt对象的基类,原型如下: QObject::QObject(Qobject *parent=0,const char *name=0) 在上面的函数中,如果parent为0则构造一个无父的对象;如果对象是一个组件,则它会成为顶层窗口。
Qt中主要的类介绍 2. QApplication • QApplication类负责GUI应用程序的控制流和主要的设置,它包括主事件循环体,负责处理和调度所有来自窗口系统和其他资源的事件 • 处理应用程序的开始,结束以及会话管理 • QApplication是QObject类的子类
Qt中主要的类介绍 3. Qwidget • QWidget是所有用户接口对象的基类,继承了 QObject类的属性 • 组件是用户界面的单元组成部分,接收鼠标, 键盘和从其它窗口系统来的事件 • QWidget类有很多成员函数,但一般不直接使用,而通过子类继承来使用其函数功能 • QWidget 是QObject类的子类
信号和槽 • 信号和槽机制是Qt的一个主要特征,是Qt与其它工具包最不相同的部分。 • 在图形用户界面编程中,经常会出现窗口的一个部件发生的变化会被通知给另一个部件。 • Qt采用信号和槽实现对象部件之间的通信
信号和槽的声明一 在Qt程序设计中,包含signals和slot的类都要加上Q_OBJECT的定义。下面给出一个在类中定义signal和slot的例子 class Student:public Qobject { Q_OBJECT public: Student() {myMark = 0;} int getMark() const {return myMark;} public slots: void setMark(int newMark); signals: void markChanged(int newMark); private: int myMark; }
信号和槽的声明二 Signal的发出一般在事件的处理函数中,利用emit发出signal,下面的例子中在事件处理结束后发出signal voidStudent::setMark(int newMark) { if(newMark != myMark) { myMark = newMark; emit markChanged(myMark); } }
信号和槽的连接一 在signal和slot声明以后,需要使用connect()函数将它们连接起来。Connect()函数属于QObject类的成员函数,能够连接signal和slot,也能够连signal和signal。函数原型如下 bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *slot) 其中第一个和第三个参数指出signal和slot属于的对象或组件
信号和槽的连接二 使用connect()函数进行连接的时候,还需要用到SIGNAL()和SLOT()两个宏,使用方法如下: QLabel*label = new QLabel; QScrollBar *scroll = new QScrollBar; QObject::connect(scroll, SIGNAL(valueChanged(int)), label, SLOT(setNum(int)));
信号和槽的连接方式一 • 同一个信号连接到多个槽 connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(updateStatusBarIndicator (int))); • 多个信号连接到同一个槽 Connect(lcd, SIGNAL(overflow()), this, SLOT(handleMathError())); Connect(calculator, SIGNAL(divisionByZero()), this, SLOT(handleMathError()));
信号和槽的连接方式二 • 一个信号连接到另外一个信号 connect(lineEdit, SIGNAL(textChanged(const Qstring&)), this, SLOT(updateRecord(const Qstring&))) • 取消一个连接 disconnect(lcd, SIGNAL(overflow()),this, SLOT(handleMathError())); 取消一个连接不是很常用,因为Qt会在一个对象被删除后自动取消这个对象所包含的所有连接
Qt安装 • Qt 下载 http://qt.nokia.com/downloads
Qt安装 • 下载安装文件Qt_SDK_Lin32_offline_v1_1_beta_en.run,在linux上安装步骤如下: 1.添加执行权限 chmod u+x Qt_SDK_Lin32_offline_v1_1_beta_en.run 2.运行安装文件 ./ Qt_SDK_Lin32_offline_v1_1_beta_en.run 3. 添加环境变量 将Qt安装目录下的bin目录加入到环境变量PATH中
Hello World程序实例 • 创建目录 mkdir /examples/hello • 创建源文件 touch hello.cpp • 编写源文件 vi hello.cpp
Hello World程序实例 • 切换到hello目录 cd /examples/hello • 创建平台独立的工程文件project file qmake –project • 创建平台独立的Makefile文件 qmake hello.pro • 编译工程 make • 运行程序 ./hello
Qt对话框 • 对话框是一种特殊的窗口,一般用来提供反馈信息或从用户获取输入。 • 给用户提供了同应用程序进行交互的方式
Qt对话框 • 模态对话框 • 最普遍的对话框。在未消失前用户不能够与同一个应用程序的其他窗口进行交互,直到该对话框关闭。 • 非模态对话框 • 当对话框打开的同时,用户还可与同一应用程序的其他窗口进行交互。
Qt对话框 • Qt对话框的类层次结构图
几种Qt内置对话框介绍 • 颜色对话框QColorDialog,允许用户选择设置颜色 • 错误对话框QErrorDialog,显示错误信息 • 文件对话框QFileDialog,允许用户选择一个或多个文件或目录 • 字体对话框QFontDialog,允许用户选择、设置字体 • 输入对话框QInputDialog,允许用户输入文本信息 • 页设置对话框QPageSetupDialog,可配置与打印相关的页面设置 • 进度对话框QProgressDialog,指示出一项操作的工作进度,而且提示用户该操作是否停滞 • 打印对话框QPrintDialog,配置打印机相关选项
几种Qt内置对话框介绍 • 颜色对话框QColorDialog,允许用户选择设置颜色 • 错误对话框QErrorDialog,显示错误信息 • 文件对话框QFileDialog,允许用户选择一个或多个文件或目录 • 字体对话框QFontDialog,允许用户选择、设置字体 • 输入对话框QInputDialog,允许用户输入文本信息 • 页设置对话框QPageSetupDialog,可配置与打印相关的页面设置 • 进度对话框QProgressDialog,指示出一项操作的工作进度,而且提示用户该操作是否停滞 • 打印对话框QPrintDialog,配置打印机相关选项
查找对话框示例 • 通过一个简单的查找对话框的实现了解Qt中对话框的创建过程,布局管理,信号和槽机制以及一些简单控件的使用
查找对话框示例 头文件finddialog.h 1 #ifndef FINDDIALOG_H 2 #define FINDDIALOG_H 3 #include <QDialog> 4 class QCheckBox; 5 class QLabel; 6 class QLineEdit; 7 class QPushButton; 8 class FindDialog : public QDialog 9 { 10 Q_OBJECT 11 public: 12 FindDialog(QWidget *parent = 0);
查找对话框示例 13signals: 14 void findNext(const QString &str, Qt::CaseSensitivity cs); 15 void findPrevious(const QString &str, Qt::CaseSensitivity cs); 16 private slots: 17 void findClicked(); 18 void enableFindButton(const QString &text); 19 private: 20 QLabel *label; 21 QLineEdit *lineEdit; 22 QCheckBox *caseCheckBox; 23 QCheckBox *backwardCheckBox; 24 QPushButton *findButton; 25 QPushButton *closeButton; 26 }; 27 #endif
查找对话框示例 • 12行FindDialog的构造函数是典型的Qt窗口部件类的定义方式。Parent参数指定了父窗口部件。该参数默认值是一个空指针,意味着该对话框没有父对象。 • 13行开始的signal部分声明了当用户单击Find按钮时对话框发出的两个信号。
查找对话框示例 1 #include <QtGui> 2 #include "finddialog.h" 3FindDialog::FindDialog(QWidget *parent) 4 : QDialog(parent) 5 { 6 label = new QLabel(tr("Find &what:")); 7 lineEdit = new QLineEdit; 8 label->setBuddy(lineEdit); 9 caseCheckBox = new QCheckBox(tr("Match &case")); 10 backwardCheckBox = new QCheckBox(tr("Search &backward")); 11 findButton = new QPushButton(tr("&Find")); 12 findButton->setDefault(true); 13 findButton->setEnabled(false); 14 closeButton = new QPushButton(tr("Close"));
查找对话框示例 15 connect(lineEdit, SIGNAL(textChanged(const QString &)), 16 this, SLOT(enableFindButton(const QString &))); 17 connect(findButton, SIGNAL(clicked()), 18 this, SLOT(findClicked())); 19 connect(closeButton, SIGNAL(clicked()), 20 this, SLOT(close()));
查找对话框示例 • 通过connect函数实现了信号和槽的连接 • 只要行编辑器中的文本发生变化,就会调用私有槽enableFindButton • 当用户单击Find按钮时,会调用findClicked私有槽 • 当用户单击Close时,对话框关闭
查找对话框示例 21QHBoxLayout *topLeftLayout = new QHBoxLayout; 22 topLeftLayout->addWidget(label); 23 topLeftLayout->addWidget(lineEdit); 24 QVBoxLayout *leftLayout = new QVBoxLayout; 25 leftLayout->addLayout(topLeftLayout); 26 leftLayout->addWidget(caseCheckBox); 27 leftLayout->addWidget(backwardCheckBox); 28 QVBoxLayout *rightLayout = new QVBoxLayout; 29 rightLayout->addWidget(findButton); 30 rightLayout->addWidget(closeButton); 31 rightLayout->addStretch(); 32 QHBoxLayout *mainLayout = new QHBoxLayout; 33 mainLayout->addLayout(leftLayout); 34 mainLayout->addLayout(rightLayout); 35 setLayout(mainLayout); 36 setWindowTitle(tr("Find")); 37 setFixedHeight(sizeHint().height()); 38 }
查找对话框示例 • Qt提供了布局管理器布局子窗口部件 • 通过QHBoxLayout,QVBoxLayout和QGridLayout这三个布局的不同嵌套组合,就可以构建出相当复杂的对话框。
查找对话框示例 39 void FindDialog::findClicked() 40 { 41 QString text = lineEdit->text(); 42 Qt::CaseSensitivity cs = 43 caseCheckBox->isChecked() ? Qt::CaseSensitive :Qt::CaseInsensitive; 44 if (backwardCheckBox->isChecked()) { 45 emit findPrevious(text, cs); 46 } else { 47 emit findNext(text, cs); 48 } 49 } 50 void FindDialog::enableFindButton(const QString &text) 51 { 52 findButton->setEnabled(!text.isEmpty()); 53 }
查找对话框示例 • 以上两个函数是对话框中用到的槽 • 当用户单击Find按钮时,就会调用findClicked槽。而该槽会发射findPrevious或findNext信号,这取决于Searchbackward选项的取值 • 只要用户改变了行编辑器中的文本,就会调用enableFindButton槽。如果在行编辑器中有文本,该槽就会启用Find按钮,否则它会禁用Find按钮
查找对话框示例 创建main.cpp文件测试FindDialog窗口部件 1 #include <QApplication> 2 #include "finddialog.h" 3 int main(int argc, char *argv[]) 4 { 5 QApplication app(argc, argv); 6 FindDialog *dialog = new FindDialog; 7 dialog->show(); 8 return app.exec(); 9 }
Qt主窗口介绍 • 应用程序的主窗口提供了用于构建应用程序用户界面的框架 • 主窗口一般包括菜单栏,工具栏,状态栏,中央窗口部件等子控件 • 在Qt中,通过子类化QMainWindow可以创建一个应用程序的主窗口
Qt主窗口介绍 • 下面通过一个简单的代码分析了解Qt中主窗口的创建过程 • 实现主窗口的源代码分别放在mainwindow.h和mainwindow.cpp中
Qt主窗口介绍 Mainwindow.h class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void newFile(); void openFile(); void cut(); void copy(); private: void createActions(); void createMenus(); void createStatusBar(); void createToolsBar();
Qt主窗口介绍 private: QMenu *fileMenu; QMenu *editMenu; QAction *newAction; QAction *openAction; QAction *cutAction; QAction *copyAction; QToolBar *fileToolBar; QToolBar *editToolBar; };
Qt主窗口介绍 • 在头文件中,将MainWindow类定义为QMainWindow的子类。 • 像File->New这样的菜单项,在MainWindow中被实现为私有槽
Qt主窗口介绍 mainwindow.cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { createActions(); createMenus(); createToolsBar(); createStatusBar(); } MainWindow类的构造函数,通过调用类的私有函数createActions(); createMenus();createToolsBar();createStatusBar();分别创建主窗口的菜单栏,工具栏和状态栏
菜单栏和工具栏 • Qt通过动作的概念简化了菜单和工具栏的编程 • 一个动作action就是一个可以添加到任意数量的菜单和工具栏上的项 • 创建菜单和工具栏一般包括如下步骤: • 创建并设置动作 • 创建菜单并把动作添加到菜单上 • 创建工具栏并把动作添加到工具栏上
菜单栏和工具栏 创建动作 void MainWindow::createActions() { //actions in fileMenu newAction = new QAction(tr("&New"),this); connect(newAction,SIGNAL(triggered()),this,SLOT(newFile())); openAction = new QAction(tr("&Open"),this); connect(openAction,SIGNAL(triggered()),this,SLOT(openFile())); //actions in editMenu cutAction = new QAction(tr("&Cut"),this); connect(cutAction,SIGNAL(triggered()),this,SLOT(cut())); copyAction = new QAction(tr("&Copy"),this); connect(copyAction,SIGNAL(triggered()),this,SLOT(copy())); }
菜单栏和工具栏 创建菜单并将动作添加到菜单上 void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAction); fileMenu->addAction(openAction); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(cutAction); editMenu->addAction(copyAction); }
菜单栏和工具栏 创建工具栏并将动作添加到工具栏上 void MainWindow::createToolsBar() { fileToolBar = addToolBar(tr("&File")); fileToolBar->addAction(newAction); fileToolBar->addAction(openAction); editToolBar = addToolBar(tr("&Edit")); editToolBar->addAction(cutAction); editToolBar->addAction(copyAction); }