Qt 基础教程:从初识到信号槽机制

目录

  • [Qt 基础教程:从初识到信号槽机制](#Qt 基础教程:从初识到信号槽机制)
    • [一、初识 Qt](#一、初识 Qt)
      • [1.1 Qt 基础类](#1.1 Qt 基础类)
      • [1.2 代码生成与导航](#1.2 代码生成与导航)
      • [1.3 继承机制](#1.3 继承机制)
      • [1.4 帮助文档使用](#1.4 帮助文档使用)
      • [1.5 Qt坐标体系](#1.5 Qt坐标体系)
    • 二、信号与槽机制
      • [2.1 connect函数详解](#2.1 connect函数详解)
      • [2.2 自动连接机制](#2.2 自动连接机制)
      • [2.3 自定义信号](#2.3 自定义信号)
      • [2.4 信号槽参数规则](#2.4 信号槽参数规则)
      • [2.5 Lambda表达式作为槽函数](#2.5 Lambda表达式作为槽函数)
      • [2.6 信号槽的意义](#2.6 信号槽的意义)
    • 三、Qt控件属性设置
      • [3.1 通用属性设置方法](#3.1 通用属性设置方法)
      • [3.2 控件访问方法总结](#3.2 控件访问方法总结)
    • 总结

Qt 基础教程:从初识到信号槽机制

一、初识 Qt

1.1 Qt 基础类

  • QWidget:所有用户界面对象的基类

1.2 代码生成与导航

cpp 复制代码
// 快速生成函数定义(在.h文件中)
// 1. 将光标放在函数声明上
// 2. 按 Alt + Enter
// 3. 选择"在.cpp中生成定义"

// 在.h和.cpp文件间切换:Fn + F4

1.3 继承机制

继承的本质是扩展

cpp 复制代码
class MyLabel : public QLabel {
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);
    ~MyLabel();  // 可添加析构函数用于日志记录
};

1.4 帮助文档使用

三种访问方式:

  1. F1键:光标放在类名/方法名上按F1
  2. Qt Creator侧边栏:点击"帮助"按钮
  3. 独立助手 :运行 assistant.exe

1.5 Qt坐标体系

左手坐标系

  • 原点:窗口左上角 (0,0)
  • X轴:向右增加
  • Y轴:向下增加

二、信号与槽机制

2.1 connect函数详解

基本语法

cpp 复制代码
connect(const QObject *sender,     // 信号发送者
        const char *signal,        // 信号函数
        const QObject *receiver,   // 接收者
        const char *method,        // 槽函数
        Qt::ConnectionType type = Qt::AutoConnection)

信号与槽的区别

特征 信号(Signal) 槽(Slot)
图标 类似wifi信号 锯齿边缘
命名 过去分词(clicked) 动词原形(click)
行为 事件发生时自动发射 可被调用的函数

实际使用示例

cpp 复制代码
// widget.cpp 构造函数中
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {
    ui->setupUi(this);
    
    QPushButton* myButton = ui->mypushButton;
    connect(myButton, &QPushButton::clicked, this, &Widget::ClickHand);
}

void Widget::ClickHand() {
    this->setWindowTitle("新的标题");
    std::cout << "点击" << std::endl;
}

2.2 自动连接机制

使用特定命名格式实现自动连接:

cpp 复制代码
// 函数命名:on_对象名_信号名()
private slots:
    void on_mypushButton_clicked();  // 自动连接按钮点击信号

注意

  1. 必须在 Qt Designer 中拖放创建控件
  2. 正确设置对象名
  3. 槽函数声明为 private slots

2.3 自定义信号

定义信号

cpp 复制代码
// widget.h
class Widget : public QWidget {
    Q_OBJECT
    
signals:  // signals 实际上是 protected 访问权限
    void mySignal();
    
private slots:
    void mySignalHander();
};

使用信号

cpp 复制代码
// widget.cpp
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {
    ui->setupUi(this);
    
    // 连接信号与槽
    connect(this, &Widget::mySignal, this, &Widget::mySignalHander);
    
    // 发射信号(可在任意位置)
    emit mySignal();  // 或 this->mySignal();
}

void Widget::mySignalHander() {
    this->setWindowTitle("新的标题!");
    std::cout << "信号处理" << std::endl;
}

2.4 信号槽参数规则

核心规则

  • 信号参数 ≥ 槽参数:允许
  • 信号参数 < 槽参数:编译错误

示例说明

cpp 复制代码
// ✅ 正确:信号参数比槽多
signals: void sig(int a, QString b);
slots: void slot(int a);  // 忽略第二个参数

// ❌ 错误:信号参数比槽少
signals: void sig(int a);
slots: void slot(int a, QString b);  // 编译错误

实际应用

cpp 复制代码
// 同一个槽连接多个信号
class MyClass {
signals:
    void signal1(int x);
    void signal2(int x, QString y);
    void signal3(int x, QString y, bool z);

slots:
    void handleAll(int x) {  // 只接收第一个参数
        qDebug() << "收到:" << x;
    }
};

2.5 Lambda表达式作为槽函数

基本语法

cpp 复制代码
[capture](parameters) -> return_type { function_body }

捕获方式

捕获方式 说明 示例
[] 不捕获外部变量 []() { ... }
[=] 值捕获所有变量 [=]() { ... }
[&] 引用捕获所有变量 [&]() { ... }
[a, &b] 混合捕获 [a, &b]() { ... }

使用示例

cpp 复制代码
QPushButton* button = new QPushButton(this);

// ❌ 错误:未捕获外部变量
connect(button, &QPushButton::clicked, []() {
    button->move(300, 300);  // 错误:button未定义
});

// ✅ 正确:显式捕获
connect(button, &QPushButton::clicked, [button]() {
    button->move(300, 300);
});

// ✅ 正确:值捕获所有
connect(button, &QPushButton::clicked, [=]() {
    button->move(300, 300);
});

2.6 信号槽的意义

  • 低耦合:减少模块间依赖,提高代码可维护性
  • 高内聚:相关功能代码集中管理,提高代码可读性

三、Qt控件属性设置

3.1 通用属性设置方法

cpp 复制代码
// 对象名和状态
btn->setObjectName("myButton");
btn->setEnabled(true);      // 启用
btn->setEnabled(false);     // 禁用

// 几何属性
btn->setGeometry(100, 50, 200, 100);  // x, y, width, height
btn->move(100, 50);                   // 只设置位置
btn->resize(200, 100);                // 只设置大小

// 尺寸策略
btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
btn->setMinimumSize(50, 30);
btn->setMaximumSize(400, 300);

// 样式属性
btn->setFont(QFont("Arial", 12, QFont::Bold));
btn->setCursor(Qt::PointingHandCursor);

// 文本内容
btn->setText("点击我");

3.2 控件访问方法总结

cpp 复制代码
// 获取控件
QPushButton* btn = ui->pushButton;  // Designer创建
QPushButton* btn = new QPushButton(this);  // 代码创建

// 设置属性
btn->setProperty("样式属性", 值);

// 连接信号槽
connect(btn, &QPushButton::clicked, this, &MyClass::handleClick);

总结

Qt的核心特性包括:

  1. 面向对象设计:丰富的类库和继承机制
  2. 信号槽机制:实现对象间低耦合通信
  3. 跨平台支持:一次编写,多平台运行
  4. 可视化开发:Qt Designer 简化界面设计
  5. 文档完善:详细的帮助文档和示例

掌握这些基础知识后,可以开始构建功能丰富的跨平台应用程序。

相关推荐
JIngJaneIL4 小时前
基于Java+ vueOA工程项目管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
蓝鲸屿4 小时前
JS基础第九天——对象(2)+Random
开发语言·前端·javascript
李绍熹5 小时前
C语言数组与指针示例
c语言·开发语言
William数据分析5 小时前
JavaScript 语法零基础入门:从变量到异步(附 Python 语法对比)
开发语言·javascript·python
刺客xs5 小时前
Qt ---- Qt6.5.3 连接MySQL数据库
数据库·qt·mysql
coderxiaohan5 小时前
【C++】无序容器unordered_set和unordered_map的使用
开发语言·c++
曹牧5 小时前
Java:Foreach语法糖
java·开发语言·python
盼哥PyAI实验室5 小时前
Python验证码处理实战:从12306项目看验证码识别的技术演进
开发语言·网络·python
222you5 小时前
SpringIOC的注解开发
java·开发语言