Skip to content

qt-信号槽机制

作用

对象间的通信机制。

特点

  • 线程安全
  • 对象解耦,一个信号可以连接多个槽,一个槽函数可以连接多个信号

使用

信号

cpp
class Button : public QWidget {
    Q_OBJECT // 生成moc_xxx.cpp的函数声明、成员变量
signals:
    void clicked();  // 无参数信号
    void valueChanged(int newValue);  // 带参数信号
};

槽函数

cpp
class Label : public QWidget {
    Q_OBJECT
public slots: // 空宏,达成注释的目的
    void onButtonClicked() {
        setText("Button clicked!");
    }
    void updateValue(int value) {
        setText(QString::number(value));
    }
};

连接方式

cpp
// 传统方式(Qt4风格,函数名错误只有在运行时才会报错)
QObject::connect(button, SIGNAL(clicked()), 
                 label, SLOT(onButtonClicked()));

// 新方式(Qt5+,编译时检查)
QObject::connect(button, &Button::clicked,
				label, &Label::onButtonClicked());

// lambda表达式
QObject::connect(button, &QPushButton::clicked, [=]() {
    label->setText("Button clicked via lambda");
});

原理

#_Later 基于Meta-Object System(元对象系统)的发布-订阅模式。

应用场景

信号和槽都在当前类

  • 一对一
cpp
// 示例:温度转换器
class TemperatureConverter : public QObject {
    Q_OBJECT
public:
    TemperatureConverter() {
        // 信号槽,连接lineEdit的textChanged信号-convertToFahrenheit槽函数
        connect(&m_celsiusEdit, &QLineEdit::textChanged,
                this, &TemperatureConverter::convertToFahrenheit);
		// 信号槽2
        connect(&m_fahrenheitEdit, &QLineEdit::textChanged,
                this, &TemperatureConverter::convertToCelsius);
    }
    
// 槽函数
private slots:
    void convertToFahrenheit(const QString &celsiusText) {
        bool ok;
        double celsius = celsiusText.toDouble(&ok);
        if (ok) {
            double fahrenheit = celsius * 9/5 + 32;
            m_fahrenheitEdit.setText(QString::number(fahrenheit));
        }
    }
    
    void convertToCelsius(const QString &fahrenheitText) {
        // 类似实现...
    }
    
private:
    QLineEdit m_celsiusEdit;
    QLineEdit m_fahrenheitEdit;
};

参考

最近更新