2011-01-14 29 views
5

Tengo trabajando en esto durante horas y no puedo entenderlo ni puedo encontrar ninguna ayuda en línea que funcione. Básicamente, la esencia de lo que estoy tratando de lograr es tener una GUI de Qt con un botón y un QTextBrowser. Cuando presiono el botón, quiero mostrar un mensaje y luego seguir imprimiendo este mensaje cada 10 segundos.Qt: ¿Cómo usar QTimer para imprimir un mensaje a QTextBrowser cada 10 segundos?

Pensé que usaría QTimer porque tiene sentido tener un temporizador para reproducir el mensaje cada 10 segundos. Cuando originalmente implementé esto en mi botón Clicked() SLOT causó que el programa se congelara. Busqué una solución en línea y encontré QApplication :: processEvents().

Así que, básicamente, en mi función que tenían algo como esto:

while(1) 
{ 
    QTimer *timer; 
    connect(...) //omitted parameters for this example  
    timer.start(10000); 
    ui->diplay->append("Message"); 

    while(timer.isActive()) 
    { 
     QApplication::processEvents() 
    } 
} 

que pensé que iba a estallar de la timer.isActive() while pero no será simplemente se queda ahí.

Así que pensé que esto era un problema de enhebrado. Así que descubrí cómo usar QThreads, pero todavía no puedo hacer que funcione. Básicamente, cuando creo un hilo con un temporizador y el hilo le dice al temporizador que comience, el programa se cierra y la consola dice "El programa ha terminado inesperadamente".

Tiene que haber una manera fácil de hacer esto, pero mi historial con Qt siempre ha sido que º

+0

ACTUALIZACIÓN: Ahora estoy usando con temporizador> SingleShot (temporizador, SEÑAL (tiempo de espera()), esto, SLOT (update())) ; Pero necesito que el programa imprima el mensaje y espere los 10 segundos antes de continuar el proceso. Lo tengo en un ciclo while por lo que constantemente hago singleShots en lugar de uno cada 10 segundos. ¿Alguna sugerencia? ¡Gracias! –

+1

¿A casi todos les falta el hecho de que esto está sucediendo en un ciclo while (1)? No es de extrañar que el programa se congele. –

Respuesta

6

Si desea mostrar su mensaje de 10 segundos, la mejor manera de hacer eso, es crear una ranura en su aplicación que borrará el mensaje. A continuación, en el botón hace clic en la ranura, añada su mensaje e inicializar un temporizador que activará su ranura de eliminación de mensajes en 10 segundos:

QTimer::singleShot(10000, this, SLOT(eraseMessageSlot())); 

Además, no hay necesidad de un hilo allí ...

+0

Pensé que necesitaba hilos porque estaba helado, pero aparentemente tenía una conexión incorrecta. –

+0

Revisa mi ACTUALIZACIÓN en el PO. ¡Gracias! –

4

Su el código tiene muchos problemas, supongo que es un pseudocódigo, esencialmente, ya que timer no existe y cosas por el estilo.

Consulte la referencia QTimer. Cuenta con un ejemplo:

QTimer *timer = new QTimer(this); 
connect(timer, SIGNAL(timeout()), this, SLOT(update())); 
timer->start(1000); 

Básicamente, usted desea hacer una ranura que se añade, a continuación, conectarlo a la señal timeout e iniciar el temporizador. El temporizador avanzará y cada segundo llamará a la ranura. En su caso, cambiaría 1000 a 10000

Si esto no funciona, ¿cuál es exactamente el problema que está teniendo? No entiendo por qué estás usando hilos, a menos que los necesites de todos modos.

EDIT Mirando su actualización, dice que quiere esperar 10 segundos. En lugar de ocupado esperando, ¿por qué no continuar el programa en su ranura (llamado por singleShot)? Creo que te falta algo de la filosofía de Qt ...

+0

Esto es básicamente lo que tuve. Parece que olvidé el 'este parámetro' y no me di cuenta. Bastante cojo teniendo en cuenta que utilicé una declaración de conexión unas líneas arriba con los parámetros correctos. Por alguna razón, el compilador no me gritó. –

1

Por defecto, QTimer disparará cada intervalo hasta que lo detengas. Es por eso que timer.isActive() es siempre cierto. Use timer.setSingleShot(true) para hacer que el temporizador se dispare solo una vez. (O use QTimer::singleShot como en la publicación de @ tibur.)

1

Pensé que el OP quería mostrar el mensaje repetidamente cada 10segundos?

En cuyo caso simplemente cree un temporizador, conecte una ranura de función updateDisplay() con la señal de temporizador y arranque el temporizador.

4

Será mejor para organizar su programa como este:

class MainWindow : QWidget //or any other parent class 
{ 
public: 
MainWindow() 
{ 
    QPushButton *button = new QPushButton(this); 
    browser_ = new QTextBrowser(this); //and some params maybe 
    QVBoxLayout * layout = new QVBoxLayout(this); //can be used another layout 
    layout->addWidget(button); 
    layout->addWidget(browser_); 

    connect(button, SIGNAL(pressed()), 
     this, SLOT(onButtonPressed())); 

    timer_ = new QTimer(this); 
    connect(timer, SIGNAL(timeout()), 
     this, SLOT(timerHandler())); 
    } 
    ~MainWindow(); 

public slots: 
    void onButtonPressed() 
    { 
     timerHandler(); //to display message when button is pressed 
     if (!timer->isActive()) timer->start(TIMER_INTERVAL); //TIMER_INTERVAL = 10000; 
    } 
    void timerHandler() 
    { 
     //put your code to display message here 
    } 

private: 
    QTextBrowser *browser_; 
    QTimer *timer_; 
} 
+0

Esta es la forma en que debería estructurarse en Qt. Cada 10 segundos, el temporizador llamará a la función timerHandler. En esa función, simplemente agregue su mensaje y salga de la función. Simple y directo, y lo más importante, no hay bucles infinitos que causen la congelación del programa. –

+0

Veo un problema con onButtonPressed(). Llamará timerHandler() independientemente de si el temporizador está activo o no. Por lo que puedo decir, el temporizador no hace nada aquí, excepto reiniciarse después de que haya transcurrido el tiempo. Este código solo mostrará el mensaje cada vez que presione el botón hasta donde yo sepa. –

+0

El temporizador se activa cuando se presiona el botón en la ranura onButtonPressed(); porque if (! timer-> isActive()) timer-> start (TIMER_INTERVAL); sera llamado – Andrew

Cuestiones relacionadas