main.cpp:
return app.exec();
qapplication.cpp:
int QApplication::exec()
{
return QGuiApplication::exec();
}
qguiapplication.cpp:
int QGuiApplication::exec()
{
#ifndef QT_NO_ACCESSIBILITY
QAccessible::setRootObject(qApp);
#endif
return QCoreApplication::exec();
}
qcoreapplication.cpp:
int QCoreApplication::exec()
{
....
int returnCode = eventLoop.exec();
....
}
qeventloop.cpp:
int QEventLoop::exec(ProcessEventsFlags flags)
{
....
while (!d->exit.loadAcquire())
processEvents(flags | WaitForMoreEvents | EventLoopExec);
....
}
大至如此,我没有仔细的看,但看来和windows类似,现代操作系统基本上都是基于事件/消息模式,QT是事件驱动的,在Windows中是Message,在Qt中是Event,Windows中有消息循环和消息派发, 在Qt中有事件循环和事件派发,so,单线程就是顺序执行,即使有中断事件的产生,也是通过发送消息/事件到队列,取消息/事件,执行消息/事件,循环往复,直至取到退出事件。
再想想,为什么定时器的时间不够准确,你定时1秒,再运行一个超过1秒的函数,定时器事件必定要在函数执行完成后才能响应定时器事件。即便系统有硬中断产生,也是同样处理,系统底层是有中断响应的,但到应用层还是通过消息/事件通知的。比如串口,如果不用多线程方式读取,在你执行一个长任务时,串口过来的数据你是不会马上读到的,如果缓冲区不够,而串口数据又太多的话,就会造成串口数据丢失,目前Qt所带的串口类好像有两种方式,一种轮询,一种是事件。
我只是想表达的是,单线程就是顺序执行,没有例外,关键是要理解这个顺序,GUI程序如同单片机程序一样,总有一个 “循环处理”:
main()
{
// 前处理
while(主线程.取出事件() != 退出)
处理事件();
// 退出后处理
}
我喜欢这样说,GUI程序中,顺序是指main()或其它入口函数中的语句执行顺序,具体到某个事件的话,要看事件在事件队列中的顺序,大致如此。
对于楼主的情况,cahwxy说的槽函数的同步控制什么的,我真心没注意去看,暂时也用不到,就偷懒了,但如果只是使用默认的参数来设置信号槽的话,那就一定是阻塞的。
当一个信号被发射时,与其相关联的槽将被立刻执行,就象一个正常的函数调用一样。
信号 - 槽机制完全独立于任何 GUI 事件循环。只有当所有的槽返回以后发射函数(emit)才返回。 如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地 执行,但是它们执行的顺序将会是随机的、不确定的,我们不能人为地指定哪个先执行、哪 个后执行。
connect(this, &MainWindow::emit1, this, &MainWindow::onSlot);
void MainWindow::on_pushButton_clicked()
{
emit this->emit1();
}
void MainWindow::onSlot()
{
j++;
qDebug() << "j" << j;
emit this->emit1();
i++;
qDebug() << i;
}
j 4262
j 4263
j 4264
j 4265
j 4266
j 4267
j 4268
j 4269
j 4270
j 4271
j 4272
j 4273
j 4274
j 4275
j 4276
j 4277
j 4278
j 4279
j 4280
j 4281
j 4282
j 4283
j 4284
j 4285
j 4286
j 4287
j 4288
j 4289
j 4290
j 4291
j 4292
j 4293
j 4294
j 4295
j 4296
j 4297
j 4298
j 4299
j 4300
j 4301
j 4302
j 4303
j 4304
j 4305
j 4306
j 4307
j 4308
j 4309
j 4310
程序异常结束。
嗯,程序永远不会i++,也许例子极端,但就是这样。
这几个字打了一小时,有监控,怕被老板发现