zoukankan      html  css  js  c++  java
  • 初探Qt中的消息处理

    Qt消息模型
    Qt封装了具体操作系统的消息机制
    Qt遵循经典的GUI消息驱动事件模型

     如果你只关注两头,即用户做某个操作,那么应用程序中的消息处理函数将被调用。

    Qt中如何表示用户消息?用字符串来描述消息
    Qt中如何映射用户消息到消息处理函数?connect
    Qt中消息映射需要遵循什么规则

    信号与槽
    Qt中定义了与系统消息相关的概念
    ——信号(Signal)
      由操作系统产生的消息
    ——槽(Slot)
      程序中的消息处理函数
    ——连接(Connect)
      将系统消息绑定到消息处理函数

    Qt中的消息处理机制

     信号到槽的连接必须发生在两个Qt类对象之间

    Qt的核心——QObject::connect函数

    bool connect(const QObject* sender,    //发送对象
                 const QObject* signal,    //消息名
                 const QObject* receiver,  //接收对象
                 const char* method,       //接受对象的成员函数
                 Qt::connectionType type = Qt::AutoConnection);

    注意:
    在Qt中,消息用字符串进行描述
    connect函数在消息名和处理函数之间建立映射

    Qt中的新关键字
    ——SIGNAL
      用于指定消息名
    ——SLOT
      用于指定消息处理函数名
    ——Q_OBJECT
      所有自定义槽的类必须在类声明的开始处加上Q_OBJECT
    ——slots
      用于在类中声明消息处理函数

    初探信号与槽

    #include <QApplication>
    #include <QPushButton>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QPushButton btn;
    
        btn.setText("click me to quit...");
    
        btn.show();
        QObject::connect(&btn, SIGNAL(clicked()),&a, SLOT(quit()) );
    
        return a.exec();
    }

    点击按钮对象,当前应用程序退出。

    自定义槽
    只有QObject的子类才能自定义槽
    定义槽的类必须在声明的最开始处使用Q_OBJECT
    类中声明槽时需要使用slots关键字
    槽与所处理的信号在函数签名上必须一致  //就是指信号如果带有参数类型,那么槽就得带有参数类型。总之两者要保持一致。
    SIGNAL和SLOT所指定的名称中:
    ——可以包含参数类型
    ——不能包含具体的参数名

    QCalculatorUI.h

    #ifndef _QCALCULATORUI_H_
    #define _QCALCULATORUIH_
    
    #include <QWidget>
    #include <QPushButton>
    #include <QLineEdit>
    
    class QCalculatorUI : public QWidget
    {
        Q_OBJECT
    private:
        QLineEdit* m_edit;
        QPushButton* m_buttons[20];
    
        QCalculatorUI();
        bool construct();
    private slots:
        void onButtonClicked();
    
    public:
        static QCalculatorUI* NewInstance();
        void show();
        ~QCalculatorUI();
    
    };
    
    #endif // _QCALCULATORUI_H_

    QCalculatorUI.cpp

    #include "QCalculatorUI.h"
    #include <QDebug>
    
    QCalculatorUI::QCalculatorUI(): QWidget(NULL,Qt::WindowCloseButtonHint) //此处QCalculatorUI就是作为顶层窗口存在的,虽然这个地方继承自QWidget,但是赋值为NULL,相当于它是没有父类的(但是实际上还是有的)。
                                                                            //将窗口中的最大化和最小化去掉
    {
        //因为QLineEdit与QCalculatorUI以及QPushButton与QCalculatorUI是组合关系,那么就应该同生死,因此需要在构造函数对其定义。因为此处涉及到在堆上申请内存空间,因此需要
        //使用二阶构造
    
    }
    
    bool QCalculatorUI::construct()
    {
        bool ret = true;
        const char* btnText[20] =
        {
            "7", "8", "9", "+", "(",
            "4", "5", "6", "-", ")",
            "1", "2", "3", "*", "<-",
            "0", ".", "=", "/", "C",
        };
    
        m_edit = new QLineEdit(this);
    
        if(m_edit != NULL)
        {
            m_edit->move(10,10);
            m_edit->resize(240,30);
            m_edit->setReadOnly(true);  //使QLineEdit只读
        }
        else
        {
            ret = false;
        }
    
        for(int i=0; (i<4) && ret; i++)
        {
            for(int j=0; (j<5) && ret; j++)
            {
                if(m_buttons[i*5 + j] != NULL)
                {
                    m_buttons[i*5 + j] = new QPushButton(this);
                    m_buttons[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i);
                    m_buttons[i*5 + j]->resize(40,40);
                    m_buttons[i*5 + j]->setText(btnText[i*5 + j]);
                    connect(m_buttons[i*5 + j],SIGNAL(clicked()), this, SLOT(onButtonClicked()));
                }
                else
                {
                    ret = false;
                }
            }
        }
    
        return ret;
    }
    
    QCalculatorUI* QCalculatorUI::NewInstance()
    {
        QCalculatorUI* ret = new QCalculatorUI();
    
        if((ret == NULL) || !(ret->construct()))
        {
            delete ret;
            ret = NULL;
        }
    
        return ret;
    }
    
    void QCalculatorUI::onButtonClicked()
    {
        QPushButton* btn = (QPushButton*)sender();
        qDebug()<< "onButtonClicked";
        qDebug() << btn->text();
    }
    void QCalculatorUI::show()
    {
        QWidget::show();
        this->setFixedSize(this->width(),this->height()); //固定窗口的大小
    }
    QCalculatorUI::~QCalculatorUI()
    {
    
    }

    main.cpp

    #include <QApplication>
    #include "QCalculatorUI.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QCalculatorUI* cal = QCalculatorUI::NewInstance();
        int ret = 0;
    
        if(cal != NULL)
        {
            cal->show();
            ret = a.exec();
            delete cal; //当程序运行到最后时,将生成的cal对象释放掉。
        }
    
        return ret;
    }

    将20个按钮映射到了同一个消息处理函数中,如何辨别哪个按钮被点击了呢?

    在消息处理函数中:QPushButton* btn = (QPushButton*)sender();,通过sender()函数获取点击了哪个按钮

  • 相关阅读:
    VC++用Recordset MSPersist载入C#DataSet Save出来的xml失败,但载入VC Recordset Save出来的xml则没问题,怎么xml不通用呢?
    观察力、分析问题的能力、与人沟通的能力和资源整合能力
    [导入]有感于神童之神源
    军训系列二:两类人创业不容易成功
    运行微软的SOAP3.0的VC样例Samples30_ADOTM_Client报错,m_pSoapClient>Invoke时直接失败
    About IM software
    [导入][转]好企业是什么样?
    动网论坛v7.0.0SQL版竟然帯病毒!
    CZoneSoft出品: 音频视频在线录制系列之 AV留言本 简介
    递归算法在生成树型结构中,几乎完全属于无稽的算法
  • 原文地址:https://www.cnblogs.com/-glb/p/12081620.html
Copyright © 2011-2022 走看看