信号和槽

信号和槽

connect

QObject::connect(
    const QObject *sender,         // 发出信号的对象
    PointerToMemberFunction signal,// 信号指针
    const QObject *receiver,       // 接收信号的对象
    PointerToMemberFunction slot   // 槽函数指针
);

Qt 信号槽中的 emit

1️⃣ emit 是什么

  • emit 不是函数,而是 Qt 定义的宏
  • 用途:标记这是一个信号的发送操作,提高代码可读性。
  • 实际作用:编译时会被替换为空,即:
emit showMainSignal();

等价于:

showMainSignal();
  • 信号本质上就是类中的一个特殊函数,emit 只是告诉读代码的人“这里是在发信号”。

2️⃣ 为什么要用 emit

  • C++ 语法允许直接调用信号函数,但可读性差。
  • Qt 引入 emit 的好处:
    1. 可读性:一眼看出这是发信号。
    2. 工具支持:Qt 的 moc 工具会扫描 emit,生成元对象代码,把信号注册到事件系统中。

3️⃣ 信号被调用的流程

emit showMainSignal(); 为例:

  1. emit 宏展开,实际调用 showMainSignal()
  2. showMainSignal() 是由 moc 自动生成的信号触发函数。
  3. 信号触发函数会:
    • 遍历所有通过 connect() 连接的槽函数
    • 按顺序调用它们(默认同步调用,线程相同)
  4. 连接的槽函数执行,例如:
MainWindow::showMainDialog(); // 显示主窗口

4️⃣ emit 的特点

  • 可省略:直接调用信号函数也能触发,但可读性差。
  • 只能调用自己类的信号:信号是受保护的(protected),外部不能直接调用。
  • 多对多通信:一个信号可以连接多个槽,一个槽也能接收多个信号。
  • 跨线程通信:如果信号和槽对象在不同线程,Qt 会用事件队列异步调用,保证线程安全。

5️⃣ 在 childDialog 中的作用

void childDialog::showMainWindow()
{
    this->hide();            // 隐藏子窗口
    emit showMainSignal();   // 通知主窗口显示
}
  • 子窗口通过 emit 发出 showMainSignal 信号。
  • 主窗口中连接的槽函数 MainWindow::showMainDialog() 会被调用。
  • 效果:子窗口隐藏,主窗口显示,实现窗口切换。

总结

  • emit 是信号触发的标识符,提高代码可读性。
  • 信号槽机制通过 connect() 连接,实现松耦合、事件驱动。
  • 信号可以跨对象、跨线程触发,Qt 会自动管理调用顺序和线程安全。

实现界面的切换

mainwindow主窗口

mainwindow窗口构造函数中实现链接

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 连接主窗口按钮点击信号 → 槽函数:显示子窗口并隐藏主窗口
    connect(ui->showChildButton, &QPushButton::clicked,
            this, &MainWindow::showChildDialog);

    // 创建子窗口实例(父对象为主窗口)
    _child_dialog = new childDialog(this);

    // 连接子窗口自定义信号 → 槽函数:显示主窗口
    connect(_child_dialog, &childDialog::showMainSignal,
            this, &MainWindow::showMainDialog);
}

MainWindow::~MainWindow()
{
    delete ui;

    // 手动释放子窗口(父子关系下可省略)
    if (_child_dialog) {
        delete _child_dialog;
        _child_dialog = nullptr;
    }
}
// 槽函数:显示子窗口并隐藏主窗口
void MainWindow::showChildDialog()
{
    this->hide();
    _child_dialog->show();
}

// 槽函数:显示主窗口
void MainWindow::showMainDialog()
{
    this->show();
}

childdialog 子窗口

childDialog::childDialog(QWidget *parent)
    : QDialog(parent)                // 调用父类构造函数,设置父对象
    , ui(new Ui::childDialog)         // 创建 UI 对象
{
    ui->setupUi(this);                // 初始化界面控件

    // 连接子窗口按钮点击信号 → 槽函数:隐藏子窗口并通知主窗口
    connect(ui->showMainButton, &QPushButton::clicked,
            this, &childDialog::showMainWindow);
}

childDialog::~childDialog()
{
    delete ui;                        // 释放 UI 资源
}

// 槽函数:隐藏子窗口并发送切换回主窗口的信号
void childDialog::showMainWindow()
{
    this->hide();                     // 隐藏当前窗口
    emit showMainSignal();            // 发送自定义信号,通知主窗口显示
}
posted @ 2025-08-13 15:00  xiaoluosibky  阅读(45)  评论(0)    收藏  举报