注意:前面都是基础讲解,如果有什么不懂的可以看看,但是如果只是追求实际运用场景,建议从问题时间开始看
这里是目录标题
原文
QEventLoop::QEventLoop(QObject *parent = nullptr)
Constructs an event loop object with the given parent.
它说,使用给定的父对象构造一个事件循环对象。
void QEventLoop::quit()
Tells the event loop to exit normally.
它说,告诉事件循环正常退出。
int QEventLoop::exec(QEventLoop::ProcessEventsFlags flags = AllEvents)
Enters the main event loop and waits until exit() is called. Returns the value that was passed to exit().
If flags are specified, only events of the types allowed by the flags will be processed.
It is necessary to call this function to start event handling. The main event loop receives events from the window system and dispatches these to the application widgets.
Generally speaking, no user interaction can take place before calling exec(). As a special case, modal widgets like QMessageBox can be used before calling exec(), because modal widgets use their own local event loop.
To make your application perform idle processing (i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout. More sophisticated idle processing schemes can be achieved using processEvents().
See also QCoreApplication::quit(), exit(), and processEvents().
它说,进入主事件循环并等待直至调用exit()。返回传递给exit()的值。若指定了标志位,则仅处理标志位允许的事件类型。必须调用此函数以启动事件处理。主事件循环接收来自窗口系统的事件,并将其分发给应用程序控件。一般而言,在调用exec()之前无法进行用户交互。特殊情况是,诸如QMessageBox之类的模态控件可在调用exec()前使用,因为模态控件使用其自身的本地事件循环。若需实现应用程序空闲处理(即当无挂起事件时执行特定函数),可使用超时时间为0的QTimer。更复杂的空闲处理方案可通过processEvents()实现。另请参阅QCoreApplication::quit()、exit()和processEvents()。
辅助理解时间
你敢想象,它可以用在哪吗?好吧,摊牌吧:
对类似于能单独开辟"工作时间"的"单元",它具有独一无二的作用,就如标题描述一样,它能直接控住这些情况。
最简单的情况来说,你们知道QTimer吧!(假装知道吧)它是我们最好的帮手,能实现异步,当然它忠于我们,并不是不可控的,不过,偶尔皮一下,假装它不可控,这时候,合理利用上述三个函数,你会发现QTimer的执行开始有趣了!
此处非必要,不要看,就是偶尔有点思维发散,皮一下:就像你家熊孩子和你去游乐园,本来按计划,让你家熊孩子自己去逛多久,然后在某个地方汇合,但是来到游乐园,你突然来感觉了,说:快,你去上个厕所(QEventLoop loop),我等你拉完......。然后,你家熊孩子一脸便秘的去上厕所......,直到它假装拉完(loop.exec())......
问题时间
好了,好了,该上点强度了,以下是某一函数内的示例代码:
c
QEventLoop loop;
int jobId = m_channel->downloadFile(remoteFilePath, localPath, QSsh::SftpOverwriteExisting);
connect(m_channel.data(), &QSsh::SftpChannel::finished, this, [&](QSsh::SftpJobId id, const QString &error) {
writeLog("[fileInfoAvailable]:" + QString().number(__LINE__));
writeLog("[fileInfoAvailable]:id " + QString().number(id) + " | jobId " + QString().number(jobId));
if (id == jobId) {
success = error.isEmpty();
if (!success) {
qDebug() << "Download failed:" << error;
}
else
{
writeLog("[fileInfoAvailable]:success");
QString newProcess1 = fileInfo.name;
newProcess = newProcess1.replace(".rar",".exe");
decompression();
progressTimer->stop();
}
loop.quit();
}
});
loop.exec();
这里涉及了lambda槽函数,SFTP网络传输,有感兴趣的@作者,作者有时间会做一个案例指导,贯穿其它技术。
在这里,SFTP网络传输不可控,你不知道它会什么时候结束。因此强行让整个程序在这里等!
如果注释掉loop.exec();,你知道会发生什么吗?提示:看看局部变量吧。希望你看到后,能开心起来。
想必,你们早就看出来了,局部变量在这个过程中的体现在这里完美展示出来。哦,忘了告诉你们,按照正常逻辑,这里的局部变量只
可能是一个定值!
案例中,局部变量jobId,在有无loop.exec()代码,会有两种结果,一种是3,一种是0。不知道你们有没有好奇过,在没有其它赋值的
情况下,它哪来的0.
0的结果其实是因为,超出作用域后导致的!哎......当我想到这一层的时候,小脑都萎缩了一下,时间久了......真尬
同步举例时间
虽然上述案例,大部分人可能不会遇见,但如果想去试试的话,可以考虑你家乖孩子,QTimer去模拟上述的情况,lambda中的参数变量可以去掉。最后,为了更加深刻明显,你可以尝试在loop.exec();后面,加个打印,你会发现,你家乖孩子,在你的监督下,进了厕所,在不知多久后,它出了厕所,然后你就可以去打印门票了。
当然,作者没有用到自家乖孩子,纯属举一反三,如有问题,欢迎指正!