2.QT-窗口组件(QWidget),QT坐标系统,初探消息处理(信号与槽)
本章主要内容如下:
- 1) 窗口组件(QWidget)
- 2) QT坐标系统
- 3) 消息处理(信号与槽)
窗口组件(QWidget)
介绍
- Qt以组件对象的方式构建图形用户界面
- Qt中没有父组件的顶级组件,则被叫做窗口
- 组件的类型分为:
- 容器类(父组件) : 用于包含功能的界面组件
- 功能类(子组件) : 用于实现特定的交互功能
如下图所示:

比如上面的QgroupBox ,即属于顶级组件的功能类(子组件),又是3个功能类组件的父组件(容器)
组件继承
Qt中所有窗口组件都继承于QWidget类,而QWidget类又继承于QObject类和QPaintDevice类.
如下图所示(只举例了3个窗口组件类):

QWidget组件介绍
- QWidget能够绘制自己(因为继承了QPaintDevice类),也能够处理用户的输入,比如点击按钮
- QWidget是Qt窗口组件类的父类
- Qt中每个窗口组件都可以当做一个QWidget (因为子类可以初始化父类)
- QWidget类对象常作为父组件或顶级组件使用
初探QWidget
1)新建工程,选择Qt Gui应用,设置类信息:

2)生成QWidget模板
运行模板:

可以看到生成了一个窗口,然后我们来看看模板代码,是如何生成的.
3)模板代码如下所示
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w; //创建QWidget类对象
w.show(); //显示QWidget类对象
return a.exec();
}
根据之前讲的内容可以发现,由于上面的QWidget w对象没有父组件,所以QWidget w便成为了没有父组件的顶级组件,从而生成了窗口.
Qt坐标系统
介绍
- Qt使用统一的坐标系统定位窗口部件的位置和大小
- QWidget类为组件类提供了窗口部件所需的坐标系统成员函数
在Qt里,坐标类型分为
- 顶级窗口部件的定位
- 窗口内部件的定位
- 窗口部件的大小设置
坐标位置示意图,如下所示

QWidget类提供的常用坐标系统成员函数有:
- resize() : 设置窗口内部的宽高( width()和height()值)
- move() : 设置整个窗口的x,y坐标( x()和y()值)
- setGeometry() : 设置窗口内部的x,y,w,h(不包括标题和窗口边框)
- size() : 获取窗口部件的大小
- pos() : 获取窗口部件的位置
- x() : 获取整个窗口x坐标
- y() : 获取整个窗口y坐标
- width() : 获取窗口内部的宽度(不包括外边框的宽度)
- height() : 获取窗口内部的高度(不包括窗口标题栏的高度)
- const QRect& geometry () : 获取窗口内部的x,y,w,h(不包括标题和窗口边框)
- const QRect& framgeometry () : 获取整个窗口的x,y,w,h
可以参考下图所示

注意: 在代码里,执行show()后, 再获取 x,y,w,h坐标 才有效
接下来我们通过3组不同的获取坐标函数,来打印(x,y,w,h)坐标信息
代码如下所示:
#include <QtGui>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
QPushButton b("button",&w); //生成 QPushButton对象, 其父组件为 QWidget
/*设置窗口大小位置*/
w.resize(,);
w.move(,);
/*设置按钮大小位置*/
b.resize(,);
b.move(,);
w.show();
qDebug()<<"QWidget:";
qDebug()<<"x()="<<w.x();
qDebug()<<"y()="<<w.y();
qDebug()<<"width()="<<w.width();
qDebug()<<"height()="<<w.height();
qDebug()<<"QWidget::geometry()";
qDebug()<<"x="<<w.geometry().x();
qDebug()<<"y="<<w.geometry().y();
qDebug()<<"w="<<w.geometry().width();
qDebug()<<"h="<<w.geometry().height();
qDebug()<<"QWidget::frameGeometry()";
qDebug()<<"x="<<w.frameGeometry().x();
qDebug()<<"y="<<w.frameGeometry().y();
qDebug()<<"w="<<w.frameGeometry().width();
qDebug()<<"h="<<w.frameGeometry().height();
return a.exec();
}
运行打印:
QWidget:
x()=
y()=
width()=
height()= QWidget::geometry()
x=
y=
w= 200
h= QWidget::frameGeometry()
x=
y=
w=
h=
可以看到,获取的窗内坐标(x,y)永远比窗外坐标大,窗外大小(w,h)永远比窗内大小大
初探消息处理(信号与槽)
QT封装了具体操作系统的消息机制,如下图所示:

Qt中定义了与系统信息相关的概念
信号(signal)
- 由操作系统产生的消息,比如按键消息
槽(slot)
- 程序中的消息处理函数,用来处理信号,比如处理按键点击信号
连接(Connect)
- 将系统信息绑定到信息处理函数(信号到槽的连接),通过connect()函数实现,且必须发生在两个Qt类对象之间,如下图所示:

connect()函数原型
bool QObject::connect (
const QObject * sender, //发送对象
const char * signal, //消息名(信息)
const QObject * receiver, //接收对象
const char * method, //接收对象的成员函数(槽)
Qt::ConnectionType type = Qt::AutoConnection ) ; //正常情况不需要设置 //当出现sender对象的signal信号,则会自动调用receiver对象的method
//连接成功,则返回true;否则返回false。
在信号与槽里,Qt引进了几个新的关键字:
- SIGNAL :指定消息名(信号),用于connect()函数里
- SLOT : 指定消息处理函数名(槽),用于connect()函数里
- Q_OBJECT : 指定该类拥有槽(消息处理),在类声明的内部开始处加上Q_OBJECT即可
- slots : 用于在类中声明消息处理函数,比如:
private slots:
void buttonCliked();
初探信号与槽
通过点击按钮,使程序自动退出,代码如下所示:
#include <QtGui>
#include <QApplication>
#include <QPushButton> int main(int argc,char * argv[])
{
QApplication app(argc,argv);
QPushButton *quitButton = new QPushButton("Quit"); QObject::connect(quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
//*quitButton(发送对象), &app(接收对象)
//quit()作用是退出程序, QApplication的成员函数
//clicked()作用是鼠标点击, 很多常用组件的成员函数 quitButton->show();
return app.exec();
}
其中上面的quit() 和clicked()都是系统预定义好的,接下来我们自定义槽
首先需要注意
- 类中声明槽(处理信号的成员函数)时,需要slots声明
- 槽和信号的函数参数必须一致,比如clicked()和quit()都是无参数的
- SIGNAL和SLOT指定的函数(信号和槽)只能包含参数类型,不能包含参数名
开始试验,通过不同按钮点击,来打印不同的信息
写QButtonDebug.h:
#ifndef QBUTTONDEBUG_H
#define QBUTTONDEBUG_H #include <QWidget>
#include <QPushButton> class QButtonDebug : public QWidget
{
Q_OBJECT //指定该类拥有slots(槽) private:
QPushButton *mbton1;
QPushButton *mbton2; private slots: //通过slots 声明 槽
void buttonCliked(); public:
explicit QButtonDebug(QWidget *parent=,Qt::WindowFlags f=);
}; #endif
写QButtonDebug.cpp:
#include "QButtonDebug.h"
#include <QDebug>
QButtonDebug:: QButtonDebug(QWidget *parent,Qt::WindowFlags f) :
QWidget(parent,f) //显示初始化父类
{
mbton1 = new QPushButton("button1",this);
mbton2 = new QPushButton("button2",this);
/*设置按钮坐标*/
mbton1->resize(,);
mbton1->move(,);
mbton2->resize(,);
mbton2->move(,);
/*设置连接*/
QObject::connect(mbton1,SIGNAL(clicked()),this,SLOT(buttonCliked()));
QObject::connect(mbton2,SIGNAL(clicked()),this,SLOT(buttonCliked()));
QWidget::show();
}
void QButtonDebug:: buttonCliked() //消息处理函数
{
QPushButton* p_buton =dynamic_cast<QPushButton*>(sender()); //获取发送信号的对象 使用
qDebug()<< p_buton->text(); //更据不同的按钮 打印不同信息
}
写main.cpp
#include <QtGui>
#include <QApplication>
#include "QButtonDebug.h" int main(int argc,char * argv[])
{
QApplication a(argc, argv); QButtonDebug b(NULL,Qt::WindowCloseButtonHint);
// Qt::WindowCloseButtonHint:去掉标题按钮提示 return a.exec();
}
运行测试
如下图所示,可以看到通过点击不同的按钮,便能打印不同的信息出来

深入信号槽-自定义信号
介绍
- 只有Qt类才能定义信号,且该类必须在头文件中声明
- 信号函数只能通过signals关键字进行声明,不能定义,且返回值必须是void类型
- 信号函数的属性会被自动设置为protected类型
- 发送信号时,只需要通过emit关键字调用信号函数即可
- 如果信号函数的参数多于槽函数时,多于的参数将被忽略
- 槽函数的返回值必须是void类型,且可以被其它普通成员函数调用
自定义信号示例:
class MySignal : public QObject
{
Q_OBJECT
signals: //自定义信号函数
void SendSignal(int i); public:
void send(int i)
{
emit SendSignal(i); //调用信号函数,发送信号
}
};
自定义槽函数示例:
class MySlot : public QObject
{
Q_OBJECT
protected slots:
void RecvSlot(int i)
{
qDebug()<<"Send:"<<sender()->objectName(); //打印发送对象名
qDebug()<<"Recv:"<<i;
qDebug()<<endl;
}
};
信号与槽的组合
- 信号函数可以连接多个槽函数
- 多个信号函数可以连接一个槽函数
- 一个信号就可以连接到另一个信号
- 通过connect函数进行连接,也可以通过disconnect函数取消连接
示例1-多个信号连接一个槽:
MySignal s1;
MySignal s2;
MySlot t; s1.setObjectName("Signal1");
s2.setObjectName("Signal2");
QObject::connect(&s1,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));
QObject::connect(&s2,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int))); s1.send();
s2.send();
打印:
Send: "Signal1"
Recv: Send: "Signal2"
Recv:
示例2-信号1连接信号2,信号2连接槽:
MySignal s1;
MySignal s2;
MySlot t;
s1.setObjectName("Signal1");
s2.setObjectName("Signal2");
QObject::connect(&s1,SIGNAL(SendSignal(int)),&s2,SIGNAL(SendSignal(int)));
QObject::connect(&s2,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));
s1.send();
s2.send();
打印:
Send: "Signal2"
Recv:
Send: "Signal2"
Recv:
2.QT-窗口组件(QWidget),QT坐标系统,初探消息处理(信号与槽)的更多相关文章
- 在Qt Creator 和在 vs2012 里添加信号和槽
原文地址:http://www.cnblogs.com/li-peng/p/3644812.html 作者:李鹏 出处:http://www.cnblogs.com/li-peng/ 本文版权归作者和 ...
- 【QT】无需写connect代码关联信号和槽函数
对于一些简单的事件判别,如点击按钮. 无需写代码关联信号和槽函数. connect(ui->Btnshowhello,SIGNAL(clicked(bool)),this,SLOT(Btnsho ...
- Qt之先用了再说系列-信号与槽
QT之信号与槽 简介:信号与槽可是Qt最大成功点,也是整个Qt基本核心机制,如果不会信号与槽,将无法领略Qt之美: 1.信号与槽函数原型: QObject::connect(const QObject ...
- 信号和槽:Qt中最差劲的创造
不要被这个标题唬住了,实际上我是非常认可Qt的.在C++实现的开源产品中没有哪一个的API风格比得上Qt,拥有高度一致性,符合常识,符合直觉,几乎不用学就可以直接上手.或许是由于我们摆脱不了马太效应的 ...
- QT中QWidget类简介
一.详细描述 QWidget类是所有用户界面对象的基类.通俗的来讲,Qt基本上所有的UI类都是由QWidget继承出来的,而QWidget继承于QObject, 大家可以查阅Qt source 即可 ...
- QT中QWidget、QDialog以及MainWindow的区别
参考 http://blog.csdn.net/u011619422/article/details/47311101 QT中QWidget.QDialog以及MainWindow的区别 QWidge ...
- Qt - QDialog,QWidget实现模态及非模态(模态Widget不能有父窗口,如果设置无边框就不能阻塞父窗口,但是可以强行设置指定Qt::Dialog,还可以setAttribute(Qt::WA_ShowModal),很多讲究)good
在Qt中QDialog为“窗口”,而QWidget为“部件”,首先还是了解下<Qt 窗口与部件的概念>. 对于 QDialog 的模态及非模态是直接可以实现的,很多课本中都会提到,此处总结 ...
- Qt:QWidget
0.说明 QWidget类是所有用户界面对象的基类. QWidget是用户界面的原子类.它接收鼠标.键盘和来自系统的其他事件,并在屏幕上将它们绘制出来.每个Widget都是矩形的,并按照Z-order ...
- Qt信号与槽自动关联机制
参考链接1:http://blog.csdn.net/skyhawk452/article/details/6121407 参考链接2:http://blog.csdn.net/memory_exce ...
随机推荐
- gogs 安装
docker 安装gogs 准备工作 安装一个mysql数据库,创建一个数据库 gogs,字符集为utf-8 查找gogs 镜像 docker search gogs 拉取镜像到本地 docker p ...
- 【Node100In1】01.去异步,解决掉Node.js万恶的回调陷阱
Node.js是基于事件驱动编程.异步函数随处可见,其中不乏一些常用库的方法.本例就以js中最常见的setTimeout的为例,试图改善一下回调的书写. 先来看一段伪代码: 我们实现一个需求,每隔一段 ...
- Struts2新漏洞S2-046在线实验环境全球首发
Strust2 又出现漏洞啦?搞事情啊? 据说S2-046漏洞和S2-045漏洞非常相似,都是由报错信息带入了buildErrorMessage方法造成的, 只是这次存在两个触发点哦!危害嘛,你说嘞? ...
- 从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
本文原作者阮一峰,作者博客:ruanyifeng.com. 1.引言 HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HT ...
- LSTM和GRU
LSTM和GRU LSTM 忽略偏置: \[\begin{align} i_t&=\sigma(x_t\cdot W_i+h_{t-1}\cdot U_i)\\ f_t&=\sigma ...
- ansible中include_tasks和import_tasks
简介 本文主要总结下ansible里task调用的方法有哪些和它们的主要区别 随着要管理的服务不断增多,我们又没将task放到roles里,会发现playbook文件越来越大,内容也越来越多,管理起 ...
- DCT(离散余弦变换)算法原理和源码(python)
原理: 离散余弦变换(DCT for Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFT for Discrete Fourier Tra ...
- multiprocessing- 基于进程的并行性
介绍 multiprocessing是一个使用类似于threading模块的API支持生成进程的包.该multiprocessing软件包提供本地和远程并发,通过使用子进程而不是线程有效地支持 全局解 ...
- (转)asyncio --- 异步 I/O
原文:https://docs.python.org/zh-cn/3/library/asyncio.html asyncio 是用来编写 并发 代码的库,使用 async/await 语法. asy ...
- 全能系统监控工具dstat
一.什么是dstat? 通过man帮助,可以看到官方对dstat的定义为:多功能系统资源统计生成工具( versatile tool for generating system resource st ...