信号和槽
信号和槽
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的好处:- 可读性:一眼看出这是发信号。
- 工具支持:Qt 的
moc工具会扫描emit,生成元对象代码,把信号注册到事件系统中。
3️⃣ 信号被调用的流程
以 emit showMainSignal(); 为例:
emit宏展开,实际调用showMainSignal()。showMainSignal()是由moc自动生成的信号触发函数。- 信号触发函数会:
- 遍历所有通过
connect()连接的槽函数 - 按顺序调用它们(默认同步调用,线程相同)
- 遍历所有通过
- 连接的槽函数执行,例如:
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(); // 发送自定义信号,通知主窗口显示
}

浙公网安备 33010602011771号