C++——Qt中的消息处理

1.Qt消息模型

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

2.一些关于系统消息的概念

  • 信号:由操作系统产生的消息
  • 槽:程序中的消息处理函数
  • 连接:将系统消息绑定到消息处理函数

QT的核心------QObject::connect函数

bool connect(const QObject* sender, //发送消息

const char* signal, //消息名

const QObject* receiver, //接收对象

const char* method, //接收对象的成员函数

Qt::ConnectionType type = Qt::AutoConnection);

3.Qt中的关键字

  • SIGNAL------用于指定消息名

  • SLOT------用于指定消息处理函数名

  • Q_OBJECT------所有自定义槽的类必须在类声明的开始处加上Q_OBJECT

  • slots------用于在类中声明消息处理函数

    #include
    #include

    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()));
    return a.exec();
    }

但上述的quit()函数是预定义的,下面我们将自定义槽:

  • 只有QObject的子类才能自定义槽
  • 定义槽的类必须在声明的最开始处使用Q_OBJECT
  • 类中声明槽时需要使用slots关键字
  • 槽与所处理的信号在函数签名上必须一致,信号的参数个数、类型 → 必须和槽的参数匹配
  • SIGNAL和SLOT所指定的名称中:可以包含参数类型、不能包含具体的参数名

完善上一章的计算器示例:

Calculatorui.h

复制代码
#ifndef QCALCULATORUI_H_
#define QCALCULATORUI_H_

#include <QWidget>
#include <QLineEdit>
#include <QPushButton>

class QCalculatorUI : public QWidget
{
    Q_OBJECT //定义槽的类必须在声明的最开始处使用Q_OBJECT
private:
    QLineEdit* m_edit;
    QPushButton* m_buttons[20];
    QCalculatorUI(); //使用二阶构造法
    bool construct();
private slots:  //类中声明槽时需要使用slots关键字
    void onButtonClicked(); //由于点击信号的函数无参数,所以槽也不能有参数
public:
    static QCalculatorUI* NewInstance();
    void show();
    ~QCalculatorUI();
};

#endif // QCALCULATORUI_H

Calculatorui.cpp

复制代码
#include "QCalculatorui.h"
#include <QDebug>

QCalculatorUI::QCalculatorUI() : QWidget(NULL, Qt::WindowCloseButtonHint) //QWidget没有父类,所以为NULL
{

}
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); //设置文本框属性为只读,不可编辑
    }
    else{
        ret = false;
    }
    for(int i = 0; (i<4) && ret; i++) {
        for(int j = 0; (j < 5) && ret; j++){
            m_buttons[i*5 + j] = new QPushButton(this); //指定这个按钮的父窗口
            if( m_buttons[i*5 + j] != NULL ){
                m_buttons[i*5 + j]->resize(40, 40);
                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()));
            }
            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::show(){
    QWidget::show();
    setFixedSize(width(), height());
}
void QCalculatorUI::onButtonClicked(){
    // sender() 返回的是通用父类指针 QObject*,强转成 QPushButton*,才能调用按钮的方法
    QPushButton* btn = (QPushButton*)sender(); //sender() 是 QObject 里的成员函数,返回当前信号的发送者
    
    QString text = m_edit->text() + btn->text();
    m_edit->setText(text);
    qDebug() << "onButtonClicked()";
    qDebug() << btn->text();

}
QCalculatorUI::~QCalculatorUI(){

}

4.点击按钮,会将对应字符串显示在输入框中:

复制代码
void QCalculatorUI::onButtonClicked(){
    // sender() 返回的是通用父类指针 QObject*,强转成 QPushButton*,才能调用按钮的方法
    QPushButton* btn = (QPushButton*)sender(); //sender() 是 QObject 里的成员函数,返回当前信号的发送者

    QString clickText = btn->text();
    if( clickText == "<-" ){ //删除一个字符
        QString text = m_edit->text();
        if( text.length() > 0){
            text.remove(text.length()-1, 1);
            m_edit->setText(text);
        }
    }
    else if( clickText == "C" ) {//清空字符
        m_edit->setText("");
    }
    else if( clickText == "=" ){

    }
    else{
         m_edit->setText(m_edit->text() + clickText);
    }

}

5.后缀表达式:将运算符放在数字后面

中缀表达式符合人类的阅读和思维习惯,后缀表达式符合计算机的运算方式,所以要将中缀表达式转为后缀表达式:

  • 将中缀表达式进行数字和运算符的分离
  • 将中缀表达式转换为后缀表达式
  • 通过后缀表达式计算最终结果
相关推荐
864记忆21 小时前
OD车牌号获取流程
qt
知识的宝藏21 小时前
Xpaht self::div 轴语法
开发语言
keykey6.21 小时前
卷积神经网络(CNN):让AI学会“看“
开发语言·人工智能·深度学习·机器学习
IsJunJianXin21 小时前
谷歌搜索cookie NID逆向生成
开发语言·python·google搜索·sgss·nid-cookie·算法生成nid·google-cookie
weikecms21 小时前
美团霸王餐报名API接口
java·开发语言
繁星蓝雨21 小时前
C++中对比pragma once和ifndef的使用区别
开发语言·c++·ifndef·头文件·pragma once
.千余21 小时前
【C++】C++手写Vector容器:从底层源码模拟实现
开发语言·c++·经验分享·笔记·学习
a诠释淡然1 天前
C++ vs Rust:哪个更适合你的下一个项目?
开发语言·c++·rust
meilindehuzi_a1 天前
深入理解 JavaScript 执行机制:从编译阶段到调用栈底层实现
开发语言·javascript·ecmascript
小小de风呀1 天前
de风——【从零开始学C++】(十二):stack和queue的基本使用和模拟实现
开发语言·c++