信号与槽——温度转换器

知识库
知识库文档
/tech-stacks/qt/examples/信号与槽——温度转换器.md

文档

Qt 信号与槽——温度转换器

目标

演示 Qt 核心机制「信号与槽」:一个摄氏/华氏温度互转的小工具,输入即实时转换。

完整代码

main.cpp

#include <QApplication>
#include "TemperatureConverter.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    TemperatureConverter window;
    window.setWindowTitle("温度转换器 - Qt 示例");
    window.resize(350, 150);
    window.show();

    return app.exec();
}

TemperatureConverter.h

#ifndef TEMPERATURECONVERTER_H
#define TEMPERATURECONVERTER_H

#include <QWidget>
#include <QLineEdit>
#include <QLabel>

class TemperatureConverter : public QWidget {
    Q_OBJECT

public:
    explicit TemperatureConverter(QWidget *parent = nullptr);

private slots:
    void onCelsiusChanged(const QString &text);
    void onFahrenheitChanged(const QString &text);

private:
    QLineEdit *celsiusInput;
    QLineEdit *fahrenheitInput;
    QLabel *statusLabel;
    bool updating = false;  // 防止信号循环
};

#endif

TemperatureConverter.cpp

#include "TemperatureConverter.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QDoubleValidator>

TemperatureConverter::TemperatureConverter(QWidget *parent)
    : QWidget(parent) {

    // 输入验证器:只允许数字
    auto *validator = new QDoubleValidator(-273.15, 10000, 2, this);

    celsiusInput = new QLineEdit(this);
    celsiusInput->setPlaceholderText("摄氏度");
    celsiusInput->setValidator(validator);

    fahrenheitInput = new QLineEdit(this);
    fahrenheitInput->setPlaceholderText("华氏度");
    fahrenheitInput->setValidator(validator);

    statusLabel = new QLabel("请在上面输入温度", this);

    // 布局
    auto *mainLayout = new QVBoxLayout(this);
    auto *inputLayout = new QHBoxLayout();
    inputLayout->addWidget(new QLabel("°C:"));
    inputLayout->addWidget(celsiusInput);
    inputLayout->addWidget(new QLabel("°F:"));
    inputLayout->addWidget(fahrenheitInput);
    mainLayout->addLayout(inputLayout);
    mainLayout->addWidget(statusLabel);

    // --- 信号与槽:Qt 的核心通信机制 ---
    connect(celsiusInput, &QLineEdit::textChanged,
            this, &TemperatureConverter::onCelsiusChanged);
    connect(fahrenheitInput, &QLineEdit::textChanged,
            this, &TemperatureConverter::onFahrenheitChanged);
}

void TemperatureConverter::onCelsiusChanged(const QString &text) {
    if (updating) return;
    bool ok;
    double c = text.toDouble(&ok);
    if (!ok || text.isEmpty()) {
        statusLabel->setText("请输入有效数字");
        return;
    }
    double f = c * 9.0 / 5.0 + 32;
    updating = true;
    fahrenheitInput->setText(QString::number(f, 'f', 2));
    updating = false;
    statusLabel->setText(QString("%1°C = %2°F").arg(c).arg(f, 0, 'f', 2));
}

void TemperatureConverter::onFahrenheitChanged(const QString &text) {
    if (updating) return;
    bool ok;
    double f = text.toDouble(&ok);
    if (!ok || text.isEmpty()) {
        statusLabel->setText("请输入有效数字");
        return;
    }
    double c = (f - 32) * 5.0 / 9.0;
    updating = true;
    celsiusInput->setText(QString::number(c, 'f', 2));
    updating = false;
    statusLabel->setText(QString("%1°F = %2°C").arg(f).arg(c, 0, 'f', 2));
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(TemperatureConverter LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)       # 关键:自动处理 Q_OBJECT 宏

find_package(Qt6 REQUIRED COMPONENTS Widgets)

add_executable(${PROJECT_NAME}
    main.cpp
    TemperatureConverter.cpp
)

target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Widgets)

运行步骤

mkdir build &;& cd build
cmake ..
make -j$(nproc)
./TemperatureConverter

关键点

  • 信号与槽是 Qt 最核心的设计:connect(sender, SIGNAL, receiver, SLOT)
  • CMAKE_AUTOMOC ON 自动处理 Q_OBJECT 宏,必须开启
  • updating 标志防止两个输入框互相触发形成无限循环
  • QDoubleValidator 限制输入为合法数值

信息

路径
/tech-stacks/qt/examples/信号与槽——温度转换器.md
更新时间
2026/5/30