I'd like to know when my application is idle so that I can preload some content. Is there an event or something similar implemented in PyQt?
我想知道我的应用程序何时处于空闲状态,以便我可以预加载一些内容。是否在PyQt中实现了类似事件?
(I could also do it with threads, but this feels like being too complicated.)
(我也可以用线程来做,但这感觉太复杂了。)
2 个解决方案
#1
You have at least two different options, you can use a thread or use a timer. Qt's QThread class provides a priority property that you can set to make it only process when no other threads are running, which includes the GUI thread. The other option is a single shot timer. A QTimer with a timeout of 0 milliseconds puts an event on the back of the event queue so that all events and synchronous functions already active or scheduled will be processed first.
您至少有两个不同的选项,您可以使用线程或使用计时器。 Qt的QThread类提供了一个优先级属性,您可以将其设置为仅在没有其他线程运行时进行处理,其中包括GUI线程。另一种选择是单发计时器。超时为0毫秒的QTimer将事件放在事件队列的后面,以便首先处理已激活或已调度的所有事件和同步函数。
In code, the two options would look like the following:
在代码中,这两个选项如下所示:
// (1) use idle thread processing
MyQThreadSubclass idleThread;
idleThread.run(QThread::IdlePriority);
// (2) use QTimer::singleShot
QTimer::singleShot(0, receiver, SLOT(doIdleProcessingChunk));
If you go with the single shot QTimer, be careful how much processing you do as you can still block the Gui. You'd likely want to break it into chunks so that GUI won't start to lag:
如果你选择单次拍摄QTimer,请注意你要做多少处理,因为你仍然可以阻挡Gui。您可能希望将其分成块,以便GUI不会开始滞后:
// slot
void doIdleProcessingChunk() {
/* ... main processing here ... */
if (chunksRemain())
QTimer::singleShot(0, receiver, SLOT(doIdleProcessingChunk));
}
Obviously, the above is C++ syntax, but to answer with respect to PyQt, use the single shot timer. In Python, the global interpreter lock is basically going to render much of your concurrency pointless if the implementation being called is performed within Python.
显然,上面是C ++语法,但要回答PyQt,请使用单次计时器。在Python中,如果被调用的实现是在Python中执行的,那么全局解释器锁基本上会使你的大部分并发变得毫无意义。
You also then have the choice of using Python threads or Qt threads, both are good for different reasons.
您也可以选择使用Python线程或Qt线程,两者都有不同的原因。
#2
Have a look at QAbstractEventDispatcher. But ... I still suggest to use a thread. Reasons:
看看QAbstractEventDispatcher。但是......我仍然建议使用一个帖子。原因:
- It will be portable
- If you make a mistake in your code, the event loop will be broken -> You app might hang, exit all of a sudden, etc.
- While the preloading happens, your app hangs. No events will be processed unless you can preload the content one at a time, they are all very small, loading takes only a few milliseconds, etc.
它将是便携式的
如果你在代码中犯了错误,事件循环将被破坏 - >你的app可能会挂起,突然退出,等等。
当预加载发生时,您的应用程序挂起。除非您可以一次预加载一个内容,它们都非常小,加载只需几毫秒等,否则不会处理任何事件。
Use a thread and send a signal to the main thread when the content is ready. It's so much more simple.
使用线程并在内容准备好后向主线程发送信号。这简单得多了。
#1
You have at least two different options, you can use a thread or use a timer. Qt's QThread class provides a priority property that you can set to make it only process when no other threads are running, which includes the GUI thread. The other option is a single shot timer. A QTimer with a timeout of 0 milliseconds puts an event on the back of the event queue so that all events and synchronous functions already active or scheduled will be processed first.
您至少有两个不同的选项,您可以使用线程或使用计时器。 Qt的QThread类提供了一个优先级属性,您可以将其设置为仅在没有其他线程运行时进行处理,其中包括GUI线程。另一种选择是单发计时器。超时为0毫秒的QTimer将事件放在事件队列的后面,以便首先处理已激活或已调度的所有事件和同步函数。
In code, the two options would look like the following:
在代码中,这两个选项如下所示:
// (1) use idle thread processing
MyQThreadSubclass idleThread;
idleThread.run(QThread::IdlePriority);
// (2) use QTimer::singleShot
QTimer::singleShot(0, receiver, SLOT(doIdleProcessingChunk));
If you go with the single shot QTimer, be careful how much processing you do as you can still block the Gui. You'd likely want to break it into chunks so that GUI won't start to lag:
如果你选择单次拍摄QTimer,请注意你要做多少处理,因为你仍然可以阻挡Gui。您可能希望将其分成块,以便GUI不会开始滞后:
// slot
void doIdleProcessingChunk() {
/* ... main processing here ... */
if (chunksRemain())
QTimer::singleShot(0, receiver, SLOT(doIdleProcessingChunk));
}
Obviously, the above is C++ syntax, but to answer with respect to PyQt, use the single shot timer. In Python, the global interpreter lock is basically going to render much of your concurrency pointless if the implementation being called is performed within Python.
显然,上面是C ++语法,但要回答PyQt,请使用单次计时器。在Python中,如果被调用的实现是在Python中执行的,那么全局解释器锁基本上会使你的大部分并发变得毫无意义。
You also then have the choice of using Python threads or Qt threads, both are good for different reasons.
您也可以选择使用Python线程或Qt线程,两者都有不同的原因。
#2
Have a look at QAbstractEventDispatcher. But ... I still suggest to use a thread. Reasons:
看看QAbstractEventDispatcher。但是......我仍然建议使用一个帖子。原因:
- It will be portable
- If you make a mistake in your code, the event loop will be broken -> You app might hang, exit all of a sudden, etc.
- While the preloading happens, your app hangs. No events will be processed unless you can preload the content one at a time, they are all very small, loading takes only a few milliseconds, etc.
它将是便携式的
如果你在代码中犯了错误,事件循环将被破坏 - >你的app可能会挂起,突然退出,等等。
当预加载发生时,您的应用程序挂起。除非您可以一次预加载一个内容,它们都非常小,加载只需几毫秒等,否则不会处理任何事件。
Use a thread and send a signal to the main thread when the content is ready. It's so much more simple.
使用线程并在内容准备好后向主线程发送信号。这简单得多了。