《Qt入门培训课件.ppt》由会员分享,可在线阅读,更多相关《Qt入门培训课件.ppt(112页珍藏版)》请在三一办公上搜索。
1、,.,Qt入门培训,Qt introduction,-,Qt简介Qt的使用Qt深入理解Qt的应用,-,Qt简介,什么是Qt?,-,什么是Qt?,原来用作用户界面开发,现可用作所有的开发例如:Databases, XML, WebKit, multimedia, networking, OpenGL, scripting, non-GUI.,”Qt 是一个用C+编写的跨平台开发框架.”,-,什么是Qt?,Qt由模块构建,QtCore,Phonon,QtXmlPatterns,QtXml,QtWebKit,QtSvg,QtSql,QtScript,QtOpenVG,QtOpenGL,QtNetwo
2、rk,QtMultimedia,QtGui,-,什么是QT?,Qt用宏(macros)和内省(introspection)扩展了C+所有的代码仍然是简明C + +,foreach (int value, intList) QObject *o = new QPustButton;o-metaObject()-className(); / 返回 ”QPushButton”connect(button, SIGNAL(clicked(), window, SLOT(close();,-,Qt的目的,一次编写,到处编译根据不同平台的本地观感生成相应的本地应用简单地使用API,高开发效率,开放性,使用
3、有趣,-,Qt的历史,1990,1991,1994,1999,2001,Haavard 和Eirik灵感闪现,开始设计,并提出信号和槽的概念,1993,开发出Qt的第一个图形核心,命名为Qt,并建立“奇趣科技”,1995,签订第一个合同,开始快速发展。,1997,Qt1.2发布, 并且用于开发KDE。,Qt 2.0发布,Qt 3.0发布。,2005,Qt 4.0发布,2008,Nokia收购奇趣科技,-,Qt的跨平台桌面平台,WindowsMac OS XLinux/Unix X11,-,Qt的跨平台嵌入式平台,Windows CESymbianMaemo嵌入式Linux,-,Qt的授权,LG
4、PL 免费你的应用程序可以是开源的或者是不开源的对Qt的修改,必须反馈到社区GPL 免费你的应用程序必须是开源的对Qt的修改,必须反馈到社区商业的 收费你的应用程序可以是不开源 的对Qt的修改,可以不开源,-,Qt简介Qt的使用Qt深入理解Qt的应用,-,Qt的代码结构-Hello World,-,Qt的代码结构-Hello World,#include #include int main( int argc, char *argv ) QApplication app( argc, argv ); QLabel l( Hello World! ); l.show(); return app.
5、exec();,-,Qt的代码结构-Hello World,#include #include int main( int argc, char *argv ) QApplication app( argc, argv ); QLabel l( Hello World! ); l.show(); return app.exec();,-,Qt的代码结构-Hello World,#include #include int main( int argc, char *argv ) QApplication app( argc, argv ); QLabel l( Hello World! ); l
6、.show(); return app.exec();,-,Qt的代码结构-Hello World,#include #include int main( int argc, char *argv ) QApplication app( argc, argv ); QLabel l( Hello World! ); l.show(); return app.exec();,-,Qt的代码结构-Hello World,#include #include int main( int argc, char *argv ) QApplication app( argc, argv ); QLabel
7、l( Hello World! ); l.show(); return app.exec();,-,Qt开发工具集,Qt CreatorQt DesignerQt LinguistQt AssisantQt Demos,-,信号(Signal)与槽(Slot)初探,QT提供的一种在对象间进行通讯的技术。动态地或松散地将事件和状态变化联系起来。信号和槽机制是使Qt运作的元素。,-,信号(Signal)与槽(Slot)初探,类似于windows中的消息和消息响应都是通过C+类成员函数实现的信号和槽是通过连接实现相互关联的包含信号或槽的类必须从QObject继承,-,信号(Signal)与槽(Slo
8、t)初探,emit clicked();,-,信号(Signal)与槽(Slot)初探,private slots: void on_addButton_clicked(); void on_deleteButton_clicked();,connect(clearButton,SIGNAL(clicked(),listWidget,SLOT(clear();,connect(addButton,SIGNAL(clicked(),this,SLOT(.);,2x,clear();,-,信号(Signal)与槽(Slot)初探, . emit clicked(); ., . emit click
9、ed(); ., . emit clicked(); ., QString newText = QInputDialog:getText(this, Enter text, Text:); if( !newText.isEmpty() ) ui-listWidget-addItem(newText);, foreach (QListWidgetItem *item, ui-listWidget-selectedItems() delete item; ,clear();,-,信号(Signal)与槽(Slot)初探,class Employee : public QObjectQ_OBJECT
10、public:Employee();int salary() const;public slots:void setSalary(int newSalary);signals:void salaryChanged(int newSalary);private:int mySalary;emit salaryChanged(50);,信号和槽的声明:,-,信号(Signal)与槽(Slot)初探,-,信号(Signal)与槽(Slot)初探,信号与槽机制只能用在继承于QObject的类。槽可以返回值,但通过联接返回时不能有返回值,槽以一个普通的函数实现,可以作为普通函数调用。信号总是返回空,信号
11、总是不必实现 一个信号可以连接到多个槽,但槽的调用顺序不确定。 信号和槽需要具有相同的参数列表;如果信号的参数比槽多,那么多余的参数会被忽略;如果参数列表不匹配,Qt会产生运行时错误信息,-,信号和槽 vs 回调,回调(callback)是一个函数指针,当一个事件发生时被调用,任何函数都可以被安排作为回调。没有类型安全总是以直接调用方式工作信号和槽的方式更加动态一个更通用的机制更容易互连两个已存在的类相关类之间涉及更少的知识共享,-,用户界面设计,用户界面由特定的部件(widget)构建,-,用户界面设计三种方式,1.绝对定位(absolute positioning )最粗劣的方式对部件的大
12、小、位置进行硬编码2. 手工布局(manual layout)绝对位置,但通过resizeEvent()方法改变大小3.布局管理器(layout managers)部件放置在布局管理器中,使界面更具弹性。,-,布局管理器的优点?,让部件适应内容让部件适应翻译变化让部件适应用户设置,-,布局管理,几种可用的布局布局管理器和部件“协商”各个部件大小与位置弹簧可以用来填充空白处,QGridLayout,QVBoxLayout,QHBoxLayout,-,布局管理器示例,对话框由多层的布局管理器和部件组成两种方式:代码实现,使用设计器,-,布局管理器代码实现,QVBoxLayout *outerLay
13、out = new QVBoxLayout(this); QHBoxLayout *topLayout = new QHBoxLayout(); topLayout-addWidget(new QLabel(Printer:); topLayout-addWidget(c=new QComboBox(); outerLayout-addLayout(topLayout); QHBoxLayout *groupLayout = new QHBoxLayout(); . outerLayout-addLayout(groupLayout); outerLayout-addSpacerItem(ne
14、w QSpacerItem(.); QHBoxLayout *buttonLayout = new QHBoxLayout(); buttonLayout-addSpacerItem(new QSpacerItem(.); buttonLayout-addWidget(new QPushButton(Print); buttonLayout-addWidget(new QPushButton(Cancel); outerLayout-addLayout(buttonLayout);,-,布局管理器代码实现,QVBoxLayout *outerLayout = new QVBoxLayout(t
15、his); QHBoxLayout *topLayout = new QHBoxLayout(); topLayout-addWidget(new QLabel(Printer:); topLayout-addWidget(c=new QComboBox(); outerLayout-addLayout(topLayout); QHBoxLayout *groupLayout = new QHBoxLayout(); . outerLayout-addLayout(groupLayout); outerLayout-addSpacerItem(new QSpacerItem(.); QHBox
16、Layout *buttonLayout = new QHBoxLayout(); buttonLayout-addSpacerItem(new QSpacerItem(.); buttonLayout-addWidget(new QPushButton(Print); buttonLayout-addWidget(new QPushButton(Cancel); outerLayout-addLayout(buttonLayout);,-,布局管理器代码实现,QVBoxLayout *outerLayout = new QVBoxLayout(this); QHBoxLayout *topL
17、ayout = new QHBoxLayout(); topLayout-addWidget(new QLabel(Printer:); topLayout-addWidget(c=new QComboBox(); outerLayout-addLayout(topLayout); QHBoxLayout *groupLayout = new QHBoxLayout(); . outerLayout-addLayout(groupLayout); outerLayout-addSpacerItem(new QSpacerItem(.); QHBoxLayout *buttonLayout =
18、new QHBoxLayout(); buttonLayout-addSpacerItem(new QSpacerItem(.); buttonLayout-addWidget(new QPushButton(Print); buttonLayout-addWidget(new QPushButton(Cancel); outerLayout-addLayout(buttonLayout);,-,布局管理器代码实现,QVBoxLayout *outerLayout = new QVBoxLayout(this); QHBoxLayout *topLayout = new QHBoxLayout
19、(); topLayout-addWidget(new QLabel(Printer:); topLayout-addWidget(c=new QComboBox(); outerLayout-addLayout(topLayout); QHBoxLayout *groupLayout = new QHBoxLayout(); . outerLayout-addLayout(groupLayout); outerLayout-addSpacerItem(new QSpacerItem(.); QHBoxLayout *buttonLayout = new QHBoxLayout(); butt
20、onLayout-addSpacerItem(new QSpacerItem(.); buttonLayout-addWidget(new QPushButton(Print); buttonLayout-addWidget(new QPushButton(Cancel); outerLayout-addLayout(buttonLayout);,-,布局管理器代码实现,QVBoxLayout *outerLayout = new QVBoxLayout(this); QHBoxLayout *topLayout = new QHBoxLayout(); topLayout-addWidget
21、(new QLabel(Printer:); topLayout-addWidget(c=new QComboBox(); outerLayout-addLayout(topLayout); QHBoxLayout *groupLayout = new QHBoxLayout(); . outerLayout-addLayout(groupLayout); outerLayout-addSpacerItem(new QSpacerItem(.); QHBoxLayout *buttonLayout = new QHBoxLayout(); buttonLayout-addSpacerItem(
22、new QSpacerItem(.); buttonLayout-addWidget(new QPushButton(Print); buttonLayout-addWidget(new QPushButton(Cancel); outerLayout-addLayout(buttonLayout);,-,布局管理器代码实现,QHBoxLayout *groupLayout = new QHBoxLayout(); QGroupBox *orientationGroup = new QGroupBox(); QVBoxLayout *orientationLayout = new QVBoxL
23、ayout(orientationGroup); orientationLayout-addWidget(new QRadioButton(Landscape); orientationLayout-addWidget(new QRadioButton(Portrait); groupLayout-addWidget(orientationGroup); QGroupBox *colorGroup = new QGroupBox(); QVBoxLayout *colorLayout = new QVBoxLayout(colorGroup); colorLayout-addWidget(ne
24、w QRadioButton(Black and White); colorLayout-addWidget(new QRadioButton(Color); groupLayout-addWidget(colorGroup);,Horizontal box, 包含 group boxes, vertical boxes, radio buttons,-,布局管理器设计器,可以使用设计器来建立同样的结构,-,通用部件,Qt包含针对所有情形的大量通用部件; 第三方控件,如QWT 自定义控件,-,尺寸(size)的策略,布局管理器是在空间和其他布局管理器之间进行协调布局管理器提供布局结构水平布局和
25、垂直布局网格布局部件则提供各个方向上的尺寸策略最大和最小尺寸,-,尺寸的策略,例子未完成!,printerList-setSizePolicy(QSizePolicy:Expanding, QSizePolicy:Fixed),-,尺寸的策略,每一个widget有一个大小的示意,它给出了各个方向上尺寸的策略Fixed 规定了widget的尺寸Minimum 规定了可能的最小值Maximum 规定可能的最大值Preferred 给出最好的值但不是必须的Expanding 同preferred,但希望增长MinimumExpanding 同minimum,但希望增长Ignored 忽略规定尺寸,
26、widget得到尽量大的空间,-,如果?,2个 preferred 相邻1个 preferred, 1个 expanding2个 expanding 相邻空间不足以放置widget (fixed),-,关于尺寸的更多信息,可用最大和最小属性更好地控制widget的大小maximumSize 最大可能尺寸minimumSize 最小可能尺寸,ui-pushButton-setMinimumSize(100, 150);ui-pushButton-setMaximumHeight(250);,-,伸缩因子,控制缩放时,各控件的缩放比例。,-,设计器介绍,以前设计器(Designer)是一个独立的工
27、具,但现在是QtCreator的一个组成部分可视化窗体编辑器拖放部件安排布局进行信号连接,-,设计器介绍,sources*.cpp,executables,object files*.o,headers*.h,generatedmoc_*.cpp,user interfaces*.ui,-,设计器介绍,sources*.cpp,executables,object files*.o,headers*.h,generatedmoc_*.cpp,generatedui_*.h,user interfaces*.ui,uic,-,使用代码,#ifndef WIDGET_H#define WIDGET
28、_H#include namespace Ui class Widget;class Widget : public QWidget Q_OBJECTpublic: Widget(QWidget *parent = 0); Widget();private: Ui:Widget *ui;#endif / WIDGET_H,Ui:Widget类的前置声明,一个 Ui:Widget 类指针ui ,指向所有部件,基本上一个标准的 QWidget 派生类,-,使用代码,#include widget.h#include ui_widget.hWidget:Widget(QWidget *parent)
29、 : QWidget(parent), ui(new Ui:Widget) ui-setupUi(this);Widget:Widget() delete ui;,实例化类Ui:Widget 为 ui,删除 ui对象,调用函数 setupUi, 生成所有父窗体 (this)的子窗体部件,-,使用设计器,基本工作流程粗略地放置部件在窗体上从里到外进行布局,添加必要的弹簧进行信号连接在代码中使用在整个过程中不断修改编辑属性实践创造完美!,-,使用设计器,拖放部件,粗略地放置部件在窗体上,-,使用设计器,从里到外进行布局,添加必要的弹簧,1,2,1. 选中每一个 group box, 2. 应用垂直
30、布局管理,-,使用设计器,从里到外进行布局,添加必要的弹簧,1,1. 选中label (click), 2. 选中combobox (Ctrl+click),2,-,使用设计器,从里到外进行布局,添加必要的弹簧,1,1. 应用一个水平布局管理,-,使用设计器,从里到外进行布局,添加必要的弹簧,1,3,1. 选中2个group box并进行布局管理, 2. 添加一个水平弹簧, 3. 将弹簧和按钮放置进一个布局管理中,2,-,使用设计器,进行信号连接(部件之间),1,2,3,4,1. 转到signals and slot 编辑模式, 2. 从一个部件拖放鼠标到另一个部件, 3. 选中signal
31、and slot, 4. 在connections dock中查看结果,-,使用设计器,进行信号连接(到你的代码中),1,2,3,1. 在widget editing 模式中 2. 右击一个部件并选择 Go to slot.3. 选择一个信号来连接到你的代码,-,使用设计器,在代码中使用通过ui类成员使用所有部件,class Widget : public QWidget .private: Ui:Widget *ui;void Widget:memberFunction() ui-pushButton-setText(.);,-,界面美化,1.子类化已有的控件类,重新实现paintEvent
32、()、MouseEvent()等方法;2.子类化QStyle,或者使用已经定义了的QWindowStyle等。3.使用StyleSheet。,-,样式表(StyleSheet),所有的 QWidget 类都有一个 styleSheet 属性以支持跨平台样式样式表是受启发自CSS的它们可以用来进行高亮处理并进行许多小的修改当然也可以用于用户界面的整体修改,-,样式表,为一个单独的部件应用一个样式表的最简单方法是用设计器,-,样式表,想为整个应用程序设定样式,可以使用 QApplication:setStyleSheet,QLineEdit background-color: yellow QLi
33、neEdit#nameEdit background-color: yellow QTextEdit, QListView background-color: white; background-image: url(draft.png); background-attachment: scroll; QGroupBox background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E0E0E0, stop: 1 #FFFFFF); border: 2px solid gray; border-radius: 5p
34、x; margin-top: 1ex; ,-,资源文件(qrc),将图标放进一个资源文件中,Qt会将它们内嵌进可执行文件避免调用多文件不需要尝试确定每个特定安装风格下的图标的路径一切都巧妙地在软件构建系统中自适应避免部署的时候出现文件丢失的错误可以将任何东西添加进资源文件中,不仅仅是图标,但一般是不需要修改的文件。,-,资源文件(qrc),可以轻松的在QtCreator中管理资源文件在路径和文件名前添加 : 以使用资源或者简单地在设计器的列表中选择一个图标,QPixmap pm(:/images/logo.png);,-,Qt的国际化,1. 确保应用程序是可翻译的: 所用用户可见的字符串都使用
35、tr()修饰 根据不同的目标语言加载不同的qm的文件。2. 即使应用程序目前不需要翻译,也应该为以后的需求留出余地。,-,Qt国际化步骤,1.在代码中使用tr()修饰用户可见的字符串;2.lupdate提取需要翻译的字符串;TRANSLATIONS = spreadsheet_cn.ts spreadsheet_en.ts 3.使用linguist工具翻译;4.在程序开始时加载正确的qm文件。,-,Qt国际化加载qm文件,int main(int argc, char *argv) QApplication app(argc, argv); . QTranslator appTranslato
36、r; appTranslator.load(myapp_ + QLocale:system().name(), qmPath); app.installTranslator( ,-,Qt国际化动态语言切换,额外的工作:语言切换的途径(菜单、按钮等);在统一的方法(RetranslateUI()内处理用户可见字符串,并在语言切换时调用该方法。实现changeEvent(QEvent *event) 方法void JournalView:changeEvent(QEvent *event) if (event-type() = QEvent:LanguageChange) retranslateU
37、i(); QTableWidget:changeEvent(event); ,-,Qt简介Qt的使用Qt深入理解Qt的应用,-,QObject类,QObject是几乎所有Qt类和所有部件(widget)的基类。它包含很多组成Qt的机制事件信号和槽属性内存管理,-,QObject类,QObject 是大部分Qt 类的基类例外的例子是:类需要作为轻量级的类,例如图元(graphical primitives)-QPen、QBrush。数据容器(QString, QList, QChar等)需要可复制的类,因为QObject类是无法被复制的。,-,QObject类,它们可以拥有一个名字 (QObje
38、ct:objectName)addButton, lineEdit_Password.它们被放置在QObject实例的一个层次上它们可以有到其他 QObject 实例的联接,“QObject 的实例是单独的!”,-,对象数据存储(1),class Personprivate: string mszName; / 姓名 bool mbSex; / 性别 int mnAge; / 年龄;,c+中定义数据变量的一般方法:,-,/ File name: person.h/ 声明私有数据成员类型struct PersonalDataPrivate; class Personpublic: Person
39、(); / constructorvirtual Person (); / destructorvoid setAge(const int);int getAge();private: PersonalDataPrivate* d;,对象数据存储(2),Qt定义数据变量(Qt 2.x):,/ File name: person.cppstruct PersonalDataPrivate / 定义私有数据成员类型 string mszName; / 姓名 bool mbSex; / 性别 int mnAge; / 年龄;/ constructorPerson:Person () d = new
40、PersonalDataPrivate;/ destructorPerson:Person () delete d;void Person:setAge(const int age) if (age != d-mnAge) d-mnAge = age;int Person:getAge() return d-mnAge;,-,元对象系统(Meta-Object System),QObject 类 作为每一个需要利用元对象系统的类的基类。Q_OBJECT 宏, 定义在每一个类的私有数据段,用来启用元对象功能,比如,动态属性,信号和槽。元对象编译器moc (the Meta Object Comp
41、lier),-,元对象系统(Meta-Object System),元对象系统的功能:元数据(QObject:metaObject)类名 (QObject:className)继承 (QObject:inherits)属性(setProperty和 QObject:property)信号和槽(Signal and slot)普通信息(QObject:classInfo)国际化(tr(), QObject:trUtf8(),-,元对象系统(Meta-Object System),sources*.cpp,executables,object files*.o,headers*.h,普通的C+生成
42、过程,includes,compiles,links,-,元数据通过元对象编译器(moc)在编译时组合在一起,元对象编译器用来处理Qt 的C+扩展。 moc从头文件里面获得数据。,sources*.cpp,executables,object files*.o,headers*.h,generatedmoc_*.cpp,Qt C+ 生成过程,includes,compiles,links,compiles,mocs,元对象系统(Meta-Object System),-,元数据,moc 找什么?,class MyClass : public QObject Q_OBJECT Q_CLASSIN
43、FO(author, John Doe)public: MyClass(const Foo ,-,内省(Introspection),类在运行时了解它们自己的信息对实现脚本和动态语言的绑定 有很好的支持。,if (object-inherits(QAbstractItemView) QAbstractItemView *view = static_cast(widget); view-.enum CapitalsEnum Oslo, Helsinki, Stockholm, Copenhagen ;int index = object-metaObject()-indexOfEnumerato
44、r(CapitalsEnum);object-metaObject()-enumerator(index)-key(object-capital();,-,属性(Properties),QObject有getter和setter函数属性命名策略: color, setColor对于布尔: isEnabled, setEnabled,class QLabel : public QFrame Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText)public: QString text() const;public slots: void
45、 setText(const QString ,-,属性,为什么使用setter 函数?可以验证设置对可能的变化作出反应,void setMin( int newMin ) if( newMin m_max ) qWarning(Ignoring setMin(%d) as min max., newMin); return; .,void setMin( int newMin ) . m_min = newMin; updateMinimum();,-,属性Properties,为什么使用getter 函数?间接的属性,QSize size() const return m_size;int
46、 width() const return m_size.width();,-,属性,Q_PROPERTY(type name READ getFunction WRITE setFunction RESET resetFunction NOTIFY notifySignal DESIGNABLE bool SCRIPTABLE bool STORED bool USER bool CONSTANT FINAL),-,使用属性,直接获取通过元信息和属性系统在运行时发现属性,QString text = label-text();label-setText(Hello World!);,QStr
47、ing text = object-property(text).toString();object-setProperty(text, Hello World);,int QMetaObject:propertyCount();QMetaProperty QMetaObject:property(i);QMetaProperty:name/isConstant/isDesignable/read/write/.,-,动态属性,在运行时给对象增加属性可以用来“标识”对象,等等。,bool ret = object-setProperty(name, value);,QObject:dynami
48、cPropertyNames() const,-,创建自定义属性,class AngleObject : public QObject Q_OBJECT Q_PROPERTY(qreal angle READ angle WRITE setAngle)public: AngleObject(qreal angle, QObject *parent = 0); qreal angle() const; void setAngle(qreal);private: qreal m_angle;,-,创建自定义属性,AngleObject:AngleObject(qreal angle, QObjec
49、t *parent) : QObject(parent), m_angle(angle)qreal AngleObject:angle() const return m_angle;void AngleObject:setAngle(qreal angle) m_angle = angle; doSomething();,-,自定义属性 - 枚举,class AngleObject : public QObject Q_OBJECT Q_ENUMS(AngleMode) Q_PROPERTY(AngleMode angleMode READ .)public: enum AngleMode R
50、adians, Degrees; .;,-,内存管理,QObject 可以有父对象和子对象当一个父对象被删除,它的子对象也同样被删除。,QObject *parent = new QObject();QObject *child1 = new QObject(parent);QObject *child2 = new QObject(parent);QObject *child1_1 = new QObject(child1);QObject *child1_2 = new QObject(child1);delete parent;,parent,child1,child2,child1_1