251006-251012 weekly Qt
最近在做一个简单的桌宠,以下记录我对C++ Qt的一些理解。
我认为,一个Qt应用主要围绕两大块:同步的UI初始化与异步的事件循环。
1. 同步的UI初始化
Qt 窗口(或任何 QWidget)的生命周期始于其构造函数。在这里,我们以常规的、同步的方式完成所有UI布局和初始属性设置。这部分代码会一次性执行完毕,构建出窗口的静态初始外观。用时可以忽略不计。
需要延时触发/用户事件驱动的部分就需要Qt特别的事件处理机制————信号与槽来实现。
2. 异步的事件循环
静态的UI只有在响应外部变化(如用户点击、网络数据到达、定时器触发)时才具有生命力。Qt 通过一个持续运行的事件循环 (Event Loop) 来管理这一切。
程序在完成同步初始化后,会交出控制权给事件循环。事件循环负责监听各种事件源,并将它们派发给相应的对象。而信号与槽 (Signals & Slots) 机制,正是 Qt 对这种异步模型优雅、类型安全的封装。
信号Signal:当某个对象的状态发生改变(如
QPushButton被点击),它会emit一个信号。信号本身不关心谁会接收它。槽Slot:一个普通的成员函数,用于响应信号。当它与一个信号
connect后,一旦信号发出,这个槽函数就会被事件循环调度执行。默认情况下:信号与槽是“同步的”。
整个流程是:事件发生 → 对象发射信号 → 事件循环 → 调度已连接的槽函数执行。
2.1. 定时触发
QTimer是Qt提供的一个定时器类,在其线程的事件循环中定期投递 timeout 事件,随后触发信号。
它是体现事件驱动的绝佳例子。
它不在当前代码流里“等待”,而是向事件循环注册一个未来的任务。
可以利用QTimer以及timeout信号来实现定时触发事件。
以下代码并不会阻塞,start() 只是告诉事件循环“请每隔1000毫秒,帮我把 timer 的 timeout 信号发出来”。
1 | QTimer *timer = new QTimer(this); |
2.2. 单次延时触发
QTimer::singleShot 是一个更便捷的静态函数,它请求事件循环“在1000毫秒后,帮我执行一次这个 Lambda 函数”。这对于实现“稍后执行”的逻辑非常有用。
1 | QTimer::singleShot(1000, this, [this](){ |
通过这种方式,复杂的异步逻辑被分解为一系列由事件驱动的、简短的槽函数调用,避免了回调地狱,也让代码结构保持清晰。
之后遇到了需要QThread的时候再介绍Qt的线程~