1. qt 入门-整体框架
总结:
本文先通过一个例子介绍了Qt项目的大致组成,即其一个简单的项目框架,如何定义窗口类,绑定信号和槽,然后初始化窗口界面,显示窗口界面,以及将程序的控制权交给Qt库。
然后主要对Qt中的信号与槽机制、Qt 元对象系统、布局管理器的概念进行分析。
---------------------------------------------
1. 下载 Qt5
http://download.qt.io/official_releases/qt/5.8/5.8.0/
2. 新建Qt 项目
具体过程见我的另一篇随笔,如何新建QT项目。
有两种创建图形化程序界面的方法,一、通过系统自动生成的.ui文件,二、通过代码实现。
方法一可通过鼠标拖拉布局界面,较方便,但在设计较复杂的界面时最好还是使用Qt提供的布局管理器。
本文的例子是采用代码实现计算圆面积的界面程序,便于展示信号与槽的通信机制以及整个程序的框架。
3. 计算圆面积的程序代码实例
整个程序的架构图如下图
程序运行界面:
4、QT项目框架分析
4.1 每一个工程都有一个执行的入口函数,此项目中的main.cpp中的 main()函数就是此工程的入口。
main.cpp
#include "dialog.h"
#include <QApplication> int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show(); return a.exec();
}
如上所示,其中:
1) #include "dialog.h" 包含了程序中要完成功能的Dialog类的定义,在Dialog类中封装完成所需要的功能。
注意:程序中使用哪个类,就要引用包含该类定义的头文件。如 dialog.h中使用QLabel、QLineEdit、QPushButton必须包含头文件
#include <QLabel> #include <QLineEdit> #include <QPushButton>
2) #include <QApplication>:Application类的定义。
3) int main(int argc, char *argv[]): 应用程序的入口,几乎在所有使用Qt的情况下,main()函数只需要在将控制权交给Qt库之前执行初始化,然后Qt 库通过事件向程序告知用户的行为。所有的Qt程序中都 必须有且只有一个main()函数。
4) QApplication a(argc, argv): a 是这个程序的 QApplication对象。
在每一个使用Qt图形化应用程序中都必须使用一个QApplication 对象。QApplication管理了各种和样的图形化应用程序的广泛资源、基本设置、控制流及事件处理等。
在任何的窗口部件被使用之前必须创建QApplication 对象。它在这里被创建并且处理这些命令行变量。所有被Qt识别的命令行参数都将从argv中被移去(并且 argc 也因此而减少)。
5) w.show():当创建一个窗口部件的时候,默认它是不可见的,必须调用show()函数使它变为可见。、
6) return a.exec():程序进入消息循环,等待可能的输入进行响应。这里就是main()函数将控制权交给Qt, Qt完成事件处理工作,当应用程序退出的时候,exec()函数的值就会返回。在exec()函数中,Qt接收并处理用户和系统的事件并且将它们传递给适当的窗口部件。
4.2 dialog.h 头文件
在类Dialog中的定义中,Q_OBJECT宏的作用是启动Qt元对象系统的一些特性(如支持信号和槽等),它必须放到类定义的私有区。
private slots: 表示下面的函数为槽函数。
dialog.h
#ifndef DIALOG_H
#define DIALOG_H #include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QGridLayout> const static double PI = 3.1416;
class Dialog : public QDialog
{
Q_OBJECT public:
Dialog(QWidget *parent = );
~Dialog(); private:
QLabel *label1, *label2;
QLineEdit *lineEdit;
QPushButton *button;
private slots:
void showArea();
}; #endif // DIALOG_H
4.3 dialog.cpp
在该文件中初始化部件,创建布局管理器,将部件加到布局管理器中,并且连接
#include "dialog.h" Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
//初始化部件
label1 = new QLabel(this);
label1->setText(tr("请输入圆的半径:"));
lineEdit = new QLineEdit(this);
label2 = new QLabel(this);
button = new QPushButton(this);
button->setText(tr("显示对应的圆的面积"));
//创建布局管理器,将部件加到布局管理器中
QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(label1,,);
mainLayout->addWidget(lineEdit,,);
mainLayout->addWidget(label2,,);
mainLayout->addWidget(button,,);
// 连接信号与槽
//分别是 点击和文本内容改变信号
connect(button,SIGNAL(clicked()),this,SLOT(showArea()));
connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(showArea()));
} Dialog::~Dialog()
{
delete label1,label2,lineEdit,button;
}
//定义槽函数
void Dialog::showArea()
{
bool ok;
QString tempStr;
QString valueStr = lineEdit->text();
int valueInt = valueStr.toInt(&ok);
double area = valueInt * valueInt * PI;
label2->setText(tempStr.setNum(area));
}
4.4 上面三部分为这个工程代码的分析,介绍了主程序中完成图形化界面程序所需的编写的代码,即窗口部件的初始化,以及窗口的使用。dialog.h dialog.cpp主要告诉如何自定义一个对话框Dialog类(继承自QDialog)即定义窗口部件,以及如何将窗口部件的信号与处理事件的槽函数进行绑定。
通过上面的分析我们可以创建一个简单的计算圆面积的图形应用程序。
5、概念解析
5.1 信号和槽机制(Signal & Slot)
Qt提供了信号和槽机制用于完成界面操作的响应,是完成任意两个Qt对象之间的通信机制。其中,信号会在某个特定的情况或动作下被触发,槽是等同于接收并处理信号的函数。
每个Qt对象都包含若干个预定义的信号和若干个预定义的槽,当某一个特定的事件发生时,一个信号被发送,与信号相关的槽则会响应信号并完成相应的处理。当一个类被继承时,该类的信号和槽也同时被继承,也可以根据需要自定义信号和槽。
1. 信号与槽的连接方式
1)一个信号可以与另一个信号相连
connect(Object1,SIGNAL(signal1),Object2,SLOT(signal2));
表示Object1的信号1可以触发Object2的信号2的发送。
2)一个信号可以与多个槽相连
connect(Object1,SIGNAL(signal1),Object2,SLOT(slot2));
connect(Object1,SIGNAL(signal1),Object3,SLOT(slot3));
3)一个槽可以响应多个信号
connect(Object1,SIGNAL(signal1),Object2,SLOT(slot2));
connect(Object3,SIGNAL(signal3),Object2,SLOT(slot2));
常用的连接方式为
connect(Object1,SIGNAL(signal),Object2,SLOT(slot));
其中,signal为Object1的信号,slot为Object2的槽
SIGNAL()和SLOT()是Qt定义的两个宏,它们返回其参数的C语言风格的字符串(const char*)。如下所示,两者等同。
connect(Object1,SIGNAL(signal),Object2,SLOT(slot));
connect(Object1,“signal”,Object2,“slot”);
2.信号与槽机制的优点
1)类型安全。需要关联的信号和槽的签名必须是等同的,即信号的参数类型和参数个数与接收该信号的槽的参数类型和参数个数相同。
但是槽的参数个数可以少于信号的参数个数,但缺少的参数必须是信号参数的最后一个或几个参数。如信号和槽的参数签名不符,编译器就会报错。
2)松散耦合。信号与槽机制减弱了Qt对象的耦合度。
激发信号的Qt对象无须知道是哪个对象的槽接收它发出的信号,它只需在适当的时候发送适当的信号即可,它不需要关心它发出的信号有没有被接收到,以及哪个对象的哪个槽接收到该信号。
对象的槽也不需要知道哪些信号关联了自己,而一旦关联信号和槽,Qt就保证了适合的槽得到了调用。即使关联的对象在运行时被删除程序也不会崩溃。
注意:一个类若要支持信号和槽,就必须从QObject或QObject的子类继承。Qt的信号和槽机制不支持对模板的使用。
3)信号与槽机制的效率
信号与槽机制增强了对象间通信的灵活性,然而损失发一些性能。同回调函数相比,信号和槽机制运行速度有些慢。通常,传递一个信号来调用槽函数将会比直接调用非虚函数运行速度慢10倍。原因如下:
a. 需要定位接收信号的对象。
b. 安全地遍历所有的关联(如一个信号关联多个槽的情况)。
c. 编组(marshal)/解组(unmarshal)传递的参数。
d. 多线程的时候,信号可能需要排队等待。
然而,与创建对象的new操作和删除对象的delete操作相比,信号和槽的运行代价只是它们很少的一部分。信号和槽机制导致的这点性能损耗,对实时应用程序是可以忽略的;同信号和槽提供的灵活性和简便性相比,这点性能损耗是值得的。 5.2 Qt5元对象系统
Qt 元对象系统提供了对象间的通信机制(信号和槽)、运行时类型信息和动态属性系统的支持,是标准C++的一个,它使Qt能够更好地实现GUI图形用户界面编程。
Qt的元对象系统不支持C++模板,尽管模板扩展了标准C++的功能,但是元对象系统提供了模板无法提供的一些特性。
Qt元对象系统基于以下三个事实。
1)基类QObject: 任何需要使用元对象系统功能的类必须继承自QObject。
2)Q_OBJECT宏:Q_OBJECT宏必须出现在类的私有声明区,用于启动元对象的特性。
3)元对象编译器 (Meta-Object Complier, moc): 为QObject子类实现元对象特性提供必要的代码实现。 5.3 布局管理器
在设计较复杂的GUI用户界面时,仅通过指定窗口部件的父子关系以期达到加载和排列窗口部件的方法是行不通的,最好的办法是使用Qt提供的布局管理器。
QGridLayout *mainLayout = new QGridLayout(this); //(a)
mainLayout->addWidget(label1,,); //(b)
mainLayout->addWidget(lineEdit,,);
mainLayout->addWidget(label2,,);
mainLayout->addWidget(button,,);
setLayout(mainLayout); //(c)
其中:
(a) QGridLayout *mainLayout = new QGridLayout(this) : 创建一个网格布局管理器对象 mainLayout, 并且 this 指出父窗口。
(b) mainLayout->addWidget(...) : 分别将控件label1等放置在该布局管理器中,还可以在创建布局管理器对象时不必指明父窗口。
(c) QWidget::setLayout(...) : 将布局管理器添加到对应的窗口部件对象中。因为这里的主窗口就是父窗口,所以直接调用 setLayout(mainLayout)即可。
1. qt 入门-整体框架的更多相关文章
- Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析
转载请注明出处:CN_Simo. 题解: 本篇内容主讲Qt应用从创建到发布的整个过程,旨在帮助读者能够快速走进Qt的世界. 本来计划是讲解Qt源码静态编译,如此的话读者可能并不能清楚地知道为何要静态编 ...
- Duilib源码分析(一)整体框架
Duilib界面库是一款由杭州月牙儿网络技术有限公司开发的界面开源库,以viksoe项目下的UiLib库的基础上开发(此后也将对UiLib库进行源码分析):通过XML布局界面,将用户界面和处理逻辑彻底 ...
- [c#]asp.net开发微信公众平台(7)前6篇的整体框架demo源码
这里给出的demo是具备整体框架的微信公众平台源码, 所谓demo就是拿过去就可以直接演示使用的东西, 当然不会具备非常详细的具体到业务层面.数据层面的东西, 每个人都可以在此基础上自由发挥, 只 ...
- Qt入门之基础篇 ( 一 ) :Qt4及Qt5的下载与安装
转载请注明出处:CN_Simo. 导语: Qt是一个跨平台的C++图形界面应用程序框架.它提供给开发者建立图形用户界面所需的功能,广泛用于开发GUI程序,也可用于开发非GUI程序.Qt很容易扩展,并且 ...
- Qt图形视图框架公开课资料
接受CSDN学院的邀请,讲一次公开课,主题是Qt图形视图框架,报名链接在这里:http://edu.csdn.net/huiyiCourse/detail/228. 内容有两部分:自定义Item和拖放 ...
- Java集合系列:-----------01集合的整体框架
内容来自:http://www.cnblogs.com/skywang12345/p/3308498.html Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映 ...
- 初识cocos2d-x-从环境配置到整体框架
前言 ACM生涯在带着些许遗憾中结束了.春招的时候找了一份游戏开发的工作,现在学习cocos2dx中. 从ACM竞赛到实际项目开发的学习,第一感觉就是不适应,虽然感觉实际项目的确要比ACM简单的多.最 ...
- Qt的Graphics-View框架和OpenGL结合详解
Qt的Graphics-View框架和OpenGL结合详解 演示程序下载地址:这里 程序源代码下载地址:这里 这是一篇纯技术文,介绍了这一个月来我抽时间研究的成果. Qt中有一个非常炫的例子:Boxe ...
- Qt入门学习——Qt 5 帮助文档的使用
Qt入门学习——Qt 5 帮助文档的使用 学习图形界面开发,肯定离不开帮助文档的使用,因为它不像 C 语言那样就那么几个函数接口,图形接口的接口可以用海量来形容,常用的我们可能能记住,其它的真的没有必 ...
- Thinkphp入门三—框架模板、变量(47)
原文:Thinkphp入门三-框架模板.变量(47) [在控制器调用模板] display() 调用当前操作名称的模板 display(‘名字’) 调用指定名字的模板文件 控制器调用模板四种方式 ...
随机推荐
- 关于NFS服务器权限的四种情况
第一种:service 和client 的UID和用户名一样 client按照service端的权限来使用.
- 让sublime可以和visual studio一样自动在运算符前后添加空格的插件
用过vs的人都知道,vs会自动在代码中运算符的前后加空格,比如 i=1; 换行后会自动变成i = 1; 开始觉得这个挺烦的,后来习惯了,发现这个功能还是挺好的,然代码更清晰. 最近换了sublimet ...
- C++ Const指针
- json字符串、json对象、数组之间的转换
json字符串转化成json对象 // jquery的方法 var jsonObj = $.parseJSON(jsonStr) //js 的方法 var jsonObj = JSON.parse(j ...
- 在python中使用正则表达式
一.转义符 1.在python中的转义符 (1)\\n与\n的区别 (2)r"\next" 通过r来进行转义 (3)"\\\\d"与"\\d" ...
- 2018.9.22 NOIP模拟赛
*注意:这套题目应版权方要求,不得公示题面. 从这里开始 Problem A 妹子 Problem B 旅程 Problem C 老大 因为业务水平下滑太严重,去和高一考NOIP模拟,sad... P ...
- STS的安装与简单使用
一,STS下载与安装 1.下载地址:http://spring.io/tools3/sts/all 2.选择对应版本安装或者解压 二,STS简单使用 1.快捷方法 (1)main+alt+/+回车 = ...
- gitlab或github下fork后如何同步源的新更新内容?
两种方式: 项目 fetch 到本地,通过命令行的方式 merge 懒人方法,只用 Github ,不用命令行 1.项目 fetch 到本地,通过命令行的方式 merge 提示:跟上游仓库同步代码之前 ...
- Redis 队列好处
Redis 队列好处 .降低流量高峰(并不是提升处理能力,系统的整体处理能力不变) .解除耦合(任务格式定好,各自演变,互不影响) .高可用(后台升级/崩溃完全不影响客户端的响应)
- Mac配置Hadoop最详细过程
Mac配置Hadoop最详细过程 原文链接: http://www.cnblogs.com/blog5277/p/8565575.html 原文作者: 博客园-曲高终和寡 https://www.cn ...