第十课、初探Qt的消息处理

一、Qt消息模型

1、Qt封装了具体操作系统的消息机制

2、Qt遵循经典的GUI消息驱动事件模型

二、信号与槽

1、Qt中定义了与系统消息相关的概念

(1)、信号(Signal):由操作系统产生的消息

(2)、槽(Slot):程序中的消息处理函数

(3)、连接(Connect):将系统消息绑定到消息处理函数

2、Qt的消息处理机制(信号到槽的连接必须发生在两个Qt对象之间)

3、Qt的核心,QObject::connect函数

(1)、在Qt中。消息用字符串来描述

(2)、connect函数在消息名和处理函数之间建立联系

4、Qt中心的关键字

(1)、SIGNAL:用于指定消息名

(2)、SLOT:用于指定消息处理函数名

(3)、Q_Object:所有自定义槽的类必须在类声明的开始处加上Q_Object

(4)、slots:用于在类中声明消息处理函数

#include <QtGui/QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QPushButton b;//顶级组件
    b.setText("click me to quit");

    b.show();

    QObject::connect(&b, SIGNAL(clicked()), &a, SLOT(quit()));//发送对象为b,消息为clicked(),接收对象为a,槽函数为quit()

    return a.exec();
}

三、自定义槽

1、自定义槽的方法

(1)、只有QObject的子类才能自定义槽

(2)、定义槽的类必须在类声明的最开始处使用Q_Object

(3)、类中声明槽函数时需要用slots关键字

(4)、槽与所处理的信号在函数签名上必须一致 

(5)、SIGNAL和SLOT所指定的名称中

A、可以包含参数类型

B、不能包含具体参数名

//主要是在头文件类声明那里加上了一下声明,在实现文件实现槽函数,连接了信号与槽

//QCalculatorUI.h:

#ifndef _QCALCULATORUI_H_
#define _QCALCULATORUI_H_

#include <QtGui/QApplication>
#include <QLineEdit>
#include <QPushButton>
#include <QDebug>

class QCalculatorUI : public QWidget//继承自Qwid,可知。QCalculatorUI是QObject的间接子类
{
    Q_OBJECT    //类声明最开始处使用Q_Object关键字
    QLineEdit* m_edit;//组合关系
    QPushButton* m_buttons[20];

    QCalculatorUI();
    bool construct();

private slots://slots关键字
    void onButtonClick();//与消息的函数签名一样,消息的clicked()没有参数,所以这里也没有

public:
    static QCalculatorUI* NewInstance();
    void show();
    ~QCalculatorUI();
};

#endif // _QCALCULATORUI_H_

//QCalculatorUI.cpp:

#include "QCalculatorUI.h"

QCalculatorUI::QCalculatorUI()  : QWidget(NULL,Qt::WindowCloseButtonHint )
{
}

bool QCalculatorUI::construct()
{

    bool ret = true;
    QLineEdit *m_edit = new QLineEdit(this);//父组件是this的原因:组合关系,同生死共存亡
    const char* btnText[20] =
    {
        "7", "8", "9", "+", "(",
        "4", "5", "6", "-", ")",
        "1", "2", "3", "*", "<-",
        "0", ".", "=", "/", "C"
    };

    if(m_edit != NULL)
    {
        m_edit->resize(240,30);
        m_edit->move(10,10);
        m_edit->setReadOnly(true);//设置文本框为只读,不输入字符串

    }
    else
    {
        ret = false;
    }

    for(int i=0; (i<4) && ret; i++)//(i<4) && ret表示QLineEdit没有生成,这里也 没必要运行了
    {
        for(int j=0; (j<5) && ret; j++)
        {
            m_buttons[i*5 + j] = new QPushButton(this);
            if(m_buttons[i*5 + j])
            {
                m_buttons[i*5 + j] ->resize(40,40);//[i*5 + j]是转换为一维来算
                m_buttons[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i);//横坐标移五个,纵坐标移四个
                m_buttons[i*5 + j]->setText(btnText[i*5 + j]);
                connect(m_buttons[i*5 + j], SIGNAL(clicked()), this, SLOT(onButtonClick()));//将信号映射到当前对象的onButtonclick()
            }
            else
            {
                ret = false;
            }

        }
    }

    return ret;

}
QCalculatorUI* QCalculatorUI::NewInstance()
{
    QCalculatorUI* ret = new QCalculatorUI();

    if(!(ret && ret->construct()))
    {
        delete ret;
        ret = NULL;
    }

    return ret;
}
void QCalculatorUI::show()
{
    QWidget::show();
    setFixedSize(width(), height());//要放在show()后,否则是先固定再显示
}

void QCalculatorUI::onButtonClick()
{
    QPushButton* btn = (QPushButton*)sender();//返回一个指向发送信号的对象的指针
    qDebug() << "onButtonClick";
    qDebug() << btn->text();
}

QCalculatorUI::~QCalculatorUI()
{

}

//main.cpp

#include <QtGui/QApplication>
#include "QCalculatorUI.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QCalculatorUI* cal = QCalculatorUI::NewInstance();
    int ret =-1;

    if(cal != NULL)
    {

        cal->show();
        ret = a.exec();
        delete cal;//记得删除父对象

    }

    return ret;
}

2、小贴士:解决经典问题QObject::connect: NO such slot

(1)、检查类是否继承于QObject

(2)、检查类声明的开始处是否添加Q_Object

(3)、检查是否使用slots关键字进行槽声明

(4)、检查槽的名称是否拼写错误

(5)、重新执行qmake

四、小结

(1)、信号与槽是Qt中的核心机制

(2)、不同的Qt对象可以通过信号与槽进行通信

(3)、只有QObject的子类才能自定义信号与槽

(4)、使用信号与槽的类必须在类声明的最开始处使用Q_Object

(5)、信号与处理函数在函数签名上必须一致(如都没有参数)

 

时间: 2024-08-04 00:10:26

第十课、初探Qt的消息处理的相关文章

第10课 初探 Qt 中的消息处理

1. Qt消息模型 (1)Qt封装了具体操作系统的消息机制 (2)Qt遵循经典的GUI消息驱动事件模型 2. 信号与槽 (1)Qt中定义了与系统消息相关的概念 ①信号(Signal):由操作系统产生的消息 ②槽(Slot):程序中的消息处理函数 ③连接(Connect):将系统消息绑定到消息处理函数(映射规则) (2)Qt中的消息处理机制 (3)Qt的核心——QObject::connect函数 ①函数原型 bool connect(const QObject* sender, //发送对象 c

QT开发(二十四)——QT文件操作

QT开发(二十四)--QT文件操作 一.QT文件操作简介 QT中的IO操作通过统一的接口简化了文件与外部设备的操作方式,QT中文件被当作一种特殊的外部设备,文件操作与外部设备操作相同. 1.IO操作的主要函数接口 打开设备:bool open(OpenMode mode) 读取数据:QByteArray read(qint64 maxSize) 写入数据:qint64 write(const QByteArray & byteArray) 关闭设备:void close() IO操作的本质是连续

QT开发(十六)——QT绘图实例-钟表

QT开发(十六)--QT绘图实例-钟表 一.钟表实现原理 钟表的实现需要设置定时器,定时器每隔一秒发送timeout()信号到QWidget::update()槽函数,update()槽函数将会重绘一次窗口,重写重绘事件函数paintEvent(QPaintEvent *event),根据获取的当前系统时间的时钟.分钟.秒钟重绘钟表的时针.分针.秒针. QTimer *timer = new QTimer(this); timer->start(1000);//一秒钟 connect(timer

QT开发(六十五)——QT样式表编程实例

QT开发(六十五)--QT样式表编程实例 一.QComboBox组合框样式定制 1.基本定义 QComboBox  {     border: 1px solid gray;     border-radius: 3px;     padding: 1px 2px 1px 2px;  # 针对于组合框中的文本内容     min-width: 9em;   # 组合框的最小宽度 } QComboBox::drop-down {     subcontrol-origin: padding;   

QT开发(十九)——QT内存泄漏问题

QT开发(十九)--QT内存泄漏问题 一.QT对象间的父子关系 QT最基础和核心的类是:QObject,QObject内部有一个list,会保存children,还有一个指针保存parent,当自己析构时,会自己从parent列表中删除并且析构所有的children. QT对象之间可以存在父子关系,每一个对象都可以保存它所有子对象的指针,每一个对象都有一个指向其父对象的指针. 当指定QT对象的父对象时,父对象会在子对象链表中加入该对象的指针,该对象会保存指向其父对象的指针. 当QT对象被销毁时,

第32课 - 初探C++ 标准库

第32课 - 初探C++ 标准库 1. 有趣的重载 操作符 << 的原生意义是按位左移,例: 1  <<  2 ; 其意义是将整数 1 按位左移 2 位,即: 0000 0001   ->    0000 0100 重载左移操作符,将变量或常量左移到一个对象中! 1 #include <stdio.h> 2 3 const char endl = '\n'; 4 5 class Console 6 { 7 public: 8 Console& operat

python学习第十课 多路复用、ThreadingTCPServer、线程与进程

python 第十课 多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作 select    poll          epoll 网络操作.文件操作.终端操作等均属于IO操作,对于windows只支持Socket操作,其他系统支持其他IO操作,但是无法检测.如普通文件操作自动上次读取是否已经变化.所以主要用来网络操作 windows 和 mac的python 只提供select,linux上的python

NeHe OpenGL教程 第十课:3D世界

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第十课:3D世界 加载3D世界,并在其中漫游: 在这一课中,你将学会如何加载3D世界,并在3D世界中漫游.这一课使用第一课的代码,当然在课程说明中我只介绍改变了代码. 这一课是由Lionel Brits (βtelgeuse)所写的

QT开发(五十五)———Qt Quick Controls

QT开发(五十五)---Qt Quick Controls 一.Qt Quick Controls基础 QT5.1发布了Qt Quick的一个全新模块:Qt Quick Controls.Qt Quick Controls模块提供了大量类似Qt Widgets模块的可重用组件. 为了开发基于Qt Quick Controls的程序,需要创建一个Qt Quick Application类型的应用程序,选择组件集的时候注意选择Qt Quick Controls. 二.Qt Quick Control