• 第十课、初探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 onButtonClicked();//与消息的函数签名一样,消息的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;

      //注意:这里隐藏了一个巨大的bug,这里又定义了一个QLineEdit,使得后面课程访问m_edit->text()时出现异常,这里应该将QLineEdit*去掉 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(onButtonClicked()));//将信号映射到当前对象的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::onButtonClicked() { 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)、信号与处理函数在函数签名上必须一致(如都没有参数

     

  • 相关阅读:
    谈我们为什么学不好编程2——你是否已进入“等死模式”?
    JSP使用SmartUpload实现文件上传
    内核模块编程练习
    Vue++:Vue中 关于$emit的用法
    Vue++:Vue 脚手架在vue.config.js文件中配置scss全局变量
    Vue++:Vuecli3.0 脚手架搭建项目
    Java++:七个开源的 Spring Boot 前后端分离项目,一定要收藏!
    MySQL++:SQL 优化的15个小技巧
    RabbitMQ++:RabbitMQ 的队列(Queue)的参数及其含义
    Vue++:Vue 二级路由不显示页面问题
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6388833.html
Copyright © 2020-2023  润新知