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 <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()));
    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.后缀表达式:将运算符放在数字后面

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

  • 将中缀表达式进行数字和运算符的分离
  • 将中缀表达式转换为后缀表达式
  • 通过后缀表达式计算最终结果
相关推荐
biter down2 小时前
深入浅出 C++ string 类:从原理到实战
开发语言·c++
okiseethenwhat2 小时前
反射在 JVM 层面的实现原理
开发语言·jvm·python
星梦清河2 小时前
Java并发编程
java·开发语言
XiYang-DING2 小时前
【Java SE】sealed关键字
java·开发语言·python
Lhan.zzZ2 小时前
Qt多线程数据库操作:安全分离连接,彻底解决段错误
数据库·c++·qt·安全
祈澈菇凉2 小时前
Next.js + OpenAI API 跑通一个带流式输出的聊天机器人
开发语言·javascript·机器人
lsx2024062 小时前
MySQL 删除数据表
开发语言
前端程序猿i2 小时前
纯JS 导出 Excel 工具
开发语言·javascript·excel
沐知全栈开发2 小时前
XML Schema 复合类型 - 仅含元素
开发语言