Cómo hacer que el programa Qt utilice Sleep
A veces veo gente en foros preguntando:
¿Por qué Qt no proporciona una función de suspensión multiplataforma?
¿Por qué en ¿La interfaz no responde después de usar el modo de suspensión o nanosueño específico de la plataforma?
QThread proporciona una función de suspensión protegida por permisos, ¿cómo puedo usarla en el hilo principal?
¿Cómo usar qSleep en QTest para ocultar la consola en Windows?
Estos problemas en realidad se reducen a un punto: usar estas funciones en el hilo principal es un error, lo que provocará directamente que la interfaz no se actualice y que el usuario no pueda interactuar con el programa.
Qt no proporciona estas funciones porque no es necesario utilizar la función de suspensión en el hilo principal.
Cómo hacer que el programa espere un período de tiempo
QTime
QTime t;
t.start();
while(t.elapsed()<1000);
Este bucle infinito también es un mal uso común. Pero es relativamente sencillo cambiarlo al bucle correcto:
QTime t;
t.start();
while(t.elapsed() < 1000)
QCoreApplication::processEvents();
Procese eventos continuamente para mantener el programa receptivo.
QElapsedTimer
Esta es una nueva clase introducida en Qt4.7 que proporciona una forma más rápida de calcular el tiempo transcurrido en comparación con QTime.
QElapsedTimer t;
t.start();
mientras(t.elapsed()<1000)
QCoreApplication:: ProcessEvents();
QTest:. qWait
Esta es la función de espera proporcionada por el módulo QTest
El siguiente es el código fuente (es muy similar). a nuestro código anterior):
espacio de nombres QTest
{
inline static void qWait(int ms)
{ p>
Q_ASSERT(QCoreApplication::instance());
Temporizador QElapsedTimer;
timer.start();
hacer {
QCoreApplication ::processEvents(QEventLoop::AllEvents, ms);
QTest:. qSleep(10);
} while (timer.elapsed() < ms) ;
}
...
Realmente no tiene nada de mágico, ¿verdad? Pero como es el módulo QTest, no deberíamos usarlo en el programa.
QEventLoop
Usar eventLoop localizado en combinación con QTimer también es una buena opción.
Ejemplo:
QEventLoop eventloop;
QTimer::singleShot(100, &eventloop, SLOT(quit()));
eventloop.exec();
QTimer y QBasicTimer
Estos dos no están directamente relacionados con este artículo y QTimer puede resultar familiar para todos. QBasicTimer rara vez se utiliza.
QBasicTimer es más rápido, más ligero y más primitivo que QTimer.
En comparación con QTimer, no es una clase derivada de QObject.
Sueño multiplataforma
Aunque dijimos al principio esto no es necesario. Pero no podemos descartar que haya situaciones en las que realmente lo necesites. ¿Cómo implementar la hibernación multiplataforma?
Como comentábamos al principio, tanto la clase QThread como el módulo QTest proporcionan funciones de suspensión, por lo que sólo necesitamos fijarnos en su código fuente:
Funciones en el módulo QTest Muy simple (Windows llama Sleep, otras plataformas llaman nanosleep):
void QTest::qSleep(int ms)
{
QTEST_ASSERT(ms > 0) ;
#ifdef Q_OS_WIN
Sleep(uint(ms));
#else
struct timespec ts = { ms / 1000 , (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
}
Buscando En el código fuente de QThread, el mismo se llama directamente en Windows.
Suspender, pero la implementación fuera de Windows es mucho más complicada que esto:
[cpp] ver copia simple
/* /internal
función auxiliar para realizar threads duerme, ya que usleep()/ nanosleep()
no son lo suficientemente confiables (en términos de comportamiento y disponibilidad)
*/
static void thread_sleep ( struct timespec *ti)
{
pthread_mutex_t mtx;
pthread_cond_t cnd; )
pthread_cond_init(&cnd, 0);
pthread_mutex_lock(&mtx);
(nulo) pthread_cond_timedwait(&cnd, &mtx, ti
pthread_mutex_unlock(&.mtx);
pthread_cond_destroy(&cnd);
pthread_mutex_destroy(&mtx); void QThread::sleep(segundos largos sin firmar)
{
struct timeval tv
gettimeofday(&tv, 0
; struct timespec ti
ti.tv_sec = tv.tv_sec + secs;
ti.tv_nsec = (tv.tv_usec * 1000); ) ;
}