Qt事情循环嵌套

时间:2019-01-25 00:28 来源:365bet线上赌球 作者:admin

本文试图解释:循环QDialog的本地事件:: EXEC(),QMenu :: exec()和等,使用后,也有很多陷阱... Qt的底漆是事件基本上所有驱动lasvamos通过QCoreApplication或其派生类exec()函数打开程序Qt的事件循环(QEventLoop):intmain(intargc,焦炭** argv的) QApplicationa(argc,argv); Returna.exec(); }但在同一个线程中,我们可以同时打开多个事件循环,例如,通过:QDialog的:: EXEC()QDrag :: EXEC()QMenu :: EXEC()......这些东西都是很常见的,不是吗? 其中每个人都在执行这样的声明:QEventLooploop;//事件循环 loop.exec();因为它在同一个线程中,显然不是并行运行,所以它只能嵌套在术语中。 演示如何? 如何可视化最小的例子说明了这个问题? 使用秒表表明它应该是最方便的。 因此,编写这样的代码很容易:#includeQtCore classObject:publicQObject 市民: Object(){startTimer(200);} 保护 voidtimerEvent(QTimerEvent *){ staticintlevel = 0; qDebug()“输入:”++ level; QEventLooploop;//事件循环 loop.exec(); qDebug()“离开:”等级; }; Intmain(intargc,char * argv[]) QCoreApplicationa(argc,argv); Objectw; Returna.exec(); 接下来,我们可以看到:输入:1 输入:2 简介:3 ......然而,令人失望的是,这不起作用。 因为在Timer事件部分期间处理了Qt:如果您当前正在处理Timer事件,则不会分发新的计时器。 实际结果是:输入:1演示了这一点,以改善这个例子:接收定时器事件发生后,我们立即把自定义的事件(事件循环,然后我们转到相应的海关英寸的本地事件)。 只要相应的计时器事件可以立即返回,就可以继续分发新的计时器事件。 另外,用于显示结果的小QPlainTextEdit用法:#includeQtGui #includeQtCore classWidget:publicQPlainTextEdit 市民: Widget(){startTimer(200);} 保护 boolevent(QEvent * EVT) 是(输入EVT()== QEvent :: timer){ QAPP-post事件(this,newQEvent(QEvent :: User)); Elseif}(类型为EVT()== QEvent :: User){ staticintlevel = 0; 等级++; 东appendPlainText(QString的( “输入:%1”)的Arg(++水平)。); QEventLooploop; loop.exec(); este-appendPlainText(QString(“Deja:%1”)arg(level)。); returnQPlainTextEdit :: event(EVT); }; Intmain(intargc,char * argv[]) QApplicationa(argc,argv); Widgetw; W.show(); Returna.exec(); }运行结果是:输入:2输入:4Insert:6Enter:8Enter:10Enter:12Enter:14进入:16Enter:18 ......是什么呢? 这个例子没有做任何事情,因为没有人似乎是编写代码的人。 但是,调用时QDialog的:: EXEC()QMenu :: EXEC()QDrag :: EXEC()...等功能,其实开始嵌套事件的周期,如果你不小心,它不各种奇怪的科目的情况下! == QDialog :: exec()vsQDialog :: Open()==?在?QDialog模式对话框与事件循环?还有呢?谈QWidget及其派生类(四)?他解释了QDialog :: exec()。 这是最后一次调用QEventLoop :: exec()。 QDialog :: exec()这是很常见的,他们通常会考虑到这个东西的负面因素。 QDialog的::打开()尽管被推荐的人员,但似乎很少有人使用,很多人可能不知道它的存在。 然而,QT官方博客:Unpredictableexec()本文介绍了EXEC()可能造成损失或,鼓励大家使用了QDialog ::打开()在官方的Qt QtQuarterly在?:?* NewWaysofUsingDialogs QtQuarterly30到了QDialog ::开(?)的详细介绍了QDialog ::打开()的优点和缺点,看一个例子:选择颜色对话框颜色,使用静态函数,写简介(EXEC内部调用()来启动事件循环)voidWidget :: onXXXClicked() QColorc = QColorDialog :: getColor(); }对话框常用,使用EXEC()启动周期事件是直观voidWidget :: onXXXClicked() QColorDialogdlg(this); dlg.exec(); QColorc = dlg.currentColor(); }使用的open(),更不直观的功能(即是异步的,需要连接插槽)voidWidget :: onXXXClicked() QColorDialog * dialog = newQColorDialog; 打开对话框(这,SLOT(dialogClosed(QColor))); voidWidget :: dialogClosed(constQColorcolor) QColor =颜色;}良好的效益(去除AndreasAardalHanssen的话):Byusingopen()insteadofexec(),youneedtowriteafewmorelinesofcode(implementingthetargetslot).Butwhatyougainisverysignificant:completecontroloverexecution.Now,theeventloopisnolongernested /重新进入,you'renotblockinginsideamagicexec)铅功能(循环崩溃KDE开发者的本地事件在博客oficialDescripción问题:Howtocrash(几乎)everyQt / KDEApplicationandhowtofixit插槽的功能,QDialog的:: EXEC()显示一个对话框。 voidParentWidget :: slotDoSomething() SomeDialogdlg(this);//在堆栈对话框中指定 如果(dlg.exec()==了QDialog ::接受){ constQStringstr = dlg.someUserInput(); // dosomethingwithwithstr }如果时间被告知ParentWidget或以其他方式(如DBUS),它必须关闭。 会发生什么? 程序崩溃:当ParentWidget析构函数将删除的对话框,并且该对话框是在栈上。 模拟简单的东西(可以加在上面的代码):voidParentWidget :: slotDoSomething() QTimer :: SingleShot(1000,这一点,SLOT(deleteLater())); ......这个博客的最后给出结论:配电箱到桩,并用QPointer保存对话框指针。 大概写成上面的代码如下:voidParentWidget :: slotDoSomething() QWeakPointerSomeDialogdlg = newSomeDialog(本); 如果(dlg.data() - EXEC()==了QDialog ::接受){ constQStringstr = dlg.data() - someUserInput(); // dosomethingwithwithstr Elseif(!Dlg){ // ... if(!DLG){ deletedlg.data(); 有兴趣可以去看看原版。 相比了QDialog ::打开()应该是更值得考虑。 当QCoreApplication :: sendPostedEvents()时做繁重,但不希望打开一个新的线程程序,选择调用QCoreApplication :: sendPostedEvents()来使程序仍然适用。 这是执行上面什么()打开本地事件循环效果实际上是什么mismo.O这一点,或QEventLoop :: EXEC()终于打来电话:QAbstractEventDispatcher :: processEvents()发送事件。 上述问题也是由您分发的事件引起的。 见Unpredictableexec()QtQuarterly32NewWaysofUsingDialogsHowtocrash(几乎)everyQt / KDEApplicationandhowtofixit
回到顶部