您的位置:首页 > 房产 > 建筑 > 市场监督管理局新式制服_重庆的网络优化公司_网站搜索引擎优化报告_市场监督管理局上班时间

市场监督管理局新式制服_重庆的网络优化公司_网站搜索引擎优化报告_市场监督管理局上班时间

2025/3/18 2:30:45 来源:https://blog.csdn.net/qq_59572329/article/details/146218837  浏览:    关键词:市场监督管理局新式制服_重庆的网络优化公司_网站搜索引擎优化报告_市场监督管理局上班时间
市场监督管理局新式制服_重庆的网络优化公司_网站搜索引擎优化报告_市场监督管理局上班时间

1. 基本概念

信号(signals):当对象的状态发生变化或发生特定事件时,自动触发的通知。比如PushButton常见的信号是clicked()信号。

槽:接收信号并执行逻辑的成员函数。可定义在类的任何部分(public、private、protected)

连接:通过QObject::connect将信号与槽绑定。connect(sender, &Sender::signal, receiver, &Receiver::slot);

2. 四种方法实现

(1)右击控件 → 转到槽(自动生成槽函数)

Qt Creator 自动生成槽函数声明和实现,并在代码中建立连接。

// 自动生成槽函数声明(头文件中)
private slots:void on_pushButton_close_clicked();// 自动生成槽函数实现(源文件中)
void OnlineMusicWidget::on_pushButton_close_clicked()
{close();
}

(2)connect函数 + 宏(旧版本)

使用 SIGNAL() 和 SLOT() 宏定义信号和槽。通过字符串匹配信号和槽,运行时解析。

connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(handleButtonClick())
);
// 槽函数声明 
public slots: void handleButtonClick();
connect(p_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandleLCDNumerTimeChangeFunc(qint64)));connect(p_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandlePositionChangeFunc(qint64)));connect(p_PlayerObject,SIGNAL(durationChanged(qint64)),this,SLOT(HandleProgressTimeChangeFunc(qint64)));// 槽函数声明
private slots:void HandleProgessTimeChangeFunc(qint64 dration);void HandlePositionChangeFunc(qint64 position);void HandleLCDNumberTimeChangeFunc(qint64 duration);

(3)connect 函数 + 地址(新版本)

使用&类名::信号 和 &类名::槽直接引用函数地址。编译时静态绑定,类型安全。

connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::handleButtonClick
);
// 槽函数声明
public slots:void handleButtonClick();
connect(p_PlayerObject,             // 发送信号的对象(例如 QMediaPlayer 实例)&QMediaPlayer::durationChanged, // 信号(当媒体时长变化时触发)this,                       // 接收槽函数的对象(当前类的实例)&MyClass::HandleProgressTimeChangeFunc // 槽函数(处理时长变化的函数)
);connect(p_PlayerObject, &QMediaPlayer::durationChanged, this, &OnlineMusicWidget::HandleProgressTimeChangeFunc);

 (4)Lambda 表达式(简化槽函数)

使用 Lambda 表达式直接处理信号逻辑。将槽函数替换为匿名函数,无需显式定义槽。


// 自动生成槽函数声明(头文件中)
private slots:void on_pushButton_close_clicked();// 自动生成槽函数实现(源文件中)
void OnlineMusicWidget::on_pushButton_close_clicked()
{close();
}// 使用 Lambda 连接点击信号connect(pushButton_close,           // 发送信号的对象&QPushButton::clicked,      // 信号this,                       // 接收者(当前窗口)[this]() {                  // Lambda 表达式(槽函数)close();                // 关闭当前窗口});
方法类型安全编译检查灵活性适用场景
转到槽快速原型开发
connect + 宏Qt 4 兼容或动态连接
connect + 地址新项目、类型安全要求高
Lambda 表达式简单逻辑、避免定义槽函数

 3. 技术细节

(1)信号与槽的元对象系统:

moc(元对象编译器):

  • Qt 的moc(元对象编辑器)工具会处理所有包含 Q_OBJECT 宏的类,生成 moc_*.cpp 文件。

  • 这些文件包含信号的实现和槽的元信息,使运行时动态连接。

元方法(Meta-Method):

  • 通过 QMetaObject 可以动态访问信号和槽:

const QMetaObject *meta = sender->metaObject();
int signalIndex = meta->indexOfSignal("valueChanged(int)");
int slotIndex = meta->indexOfSlot("handleValue(int)");
QMetaObject::connect(sender, signalIndex, receiver, slotIndex);

(2)信号的重载处理

强制类型转换解决重载歧义

// 假设信号有重载:void valueChanged(int) 和 void valueChanged(QString)
connect(sender,static_cast<void (SenderClass::*)(int)>(&SenderClass::valueChanged),receiver,&ReceiverClass::handleIntValue
);

(3)信号与槽的返回值

  • 信号无返回值:所有信号必须返回 void

  • 槽可以有返回值,但通常不推荐

4. 高级用法

(1)信号与信号连接

  • 信号转发:一个信号触发另一个信号,用于抽象或代理。

connect(button, &QPushButton::clicked,this, &MainWindow::startProcessingSignal
);

 (2)跨线程通信(QueuedConnection)

  • 异步执行:确保槽在接收者线程执行。

connect(workerThread, &Worker::resultReady,mainThread, &MainWindow::updateUI,Qt::QueuedConnection
);

(4)Lambda 表达式进阶

  • 捕获上下文变量:

int threshold = 100;
connect(slider, &QSlider::valueChanged,[threshold, this](int value) {if (value > threshold) this->alert();}
);
  • 处理信号参数:
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged),[](int value) { qDebug() << "Value:" << value; }
);

4. 底层原理

(1)信号的本质

  • 信号是普通函数:由 moc 生成,内部调用 QMetaObject::activate

(2)槽的调用机制

  • 直接连接(DirectConnection):立即在发送者线程调用槽函数。

  • 队列连接(QueuedConnection):将槽调用封装为事件,投递到接收者线程的事件循环。

(3)事件循环与信号槽

  • 信号槽依赖事件循环:队列连接和跨线程通信需要运行 QCoreApplication::exec()

  • 无事件循环的场景(如纯计算线程),需谨慎使用队列连接。

5. 实际案例

(1)动态界面更新

// 根据数据变化动态更新多个 UI 控件
connect(dataModel, &DataModel::dataChanged,this, [this](int index) {updateChart(index);updateTable(index);logChange(index);}
);

(2)异步任务链

// 链式异步操作(下载 → 解析 → 显示)
connect(downloader, &Downloader::finished,parser, &DataParser::parse,Qt::QueuedConnection
);
connect(parser, &DataParser::parsed,this, &MainWindow::showResult,Qt::QueuedConnection
);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com