PDA

View Full Version : QTimer based Splash Screen



bpetty
14th December 2006, 00:49
Hey guys,

I have a dialog widget setup to be a custom splash screen.
I am overriding paintEvent to draw some boxes on the widget.
I have a QTimer setup to run a method every half second or so.
This method updates an array and does a repaint() wich calls
paintEvent. The code in paintEvent draws the boxes on the dialog
with different opacities based on values in the array.

My problem is that my QTimer is not triggering my method.

Here is my code:


CINWaitSplash::CINWaitSplash(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
// Main Event Timer
m_timerMain = new QTimer(this);
connect(m_timerMain, SIGNAL(timeout()), this, SLOT(FillTable_SnakePattern()));
m_timerMain->setInterval(100); // Start our Timer 1000 = 1sec
m_timerMain->setSingleShot(false);
}


My MainWindow has a routine that calls these to start and stop the timer:


void CINWaitSplash::Start()
{
InitTable(); // Start A Blank Table

this->show(); // Show Dialog

m_timerMain->start();
}

void CINWaitSplash::Stop()
{
m_timerMain->stop();

this->hide(); // Hide Dialog
}


So when I call Start() it displays my Dialog Widget and "starts" the timer. My MainWindow sleeps for like 10 seconds then calls Stop(). It is doing that just for testing. Anyways... my FillTable_SnakePattern() method never gets triggered by the timer. At the end of the method I am doing a repaint() like I said earlier. I am going to use this to pop up a slash screen when you do a search in my program. When the search is done, it will call Stop() and hide the splash screen.

Am I doing something wrong here? I am assuming the timer runs on another thread... right?

So if I accessed my splashscreen class like this from my mainwindow:

CINWaitSplash* CINMainWindow::INWaitSplash() { return m_qtINWaitSplash; }

I would be able to start and stop it like so:

INMainWindow()->INWaitSplash()->Start();
// sleep 10 seconds
INMainWindow()->INWaitSplash()->Stop();

jacek
14th December 2006, 01:01
Are there any messages on the console? Did you add Q_OBJECT macro and declared FillTable_SnakePattern() as a slot?

wysota
14th December 2006, 01:12
Do you have an event loop running?

bpetty
14th December 2006, 14:48
Header File:


#ifndef __INWAITSPLASH_H__
#define __INWAITSPLASH_H__

#include "ui_INWaitSplash.h"

#define ROWSIZE 4
#define COLUMNSIZE 4
#define TAILLENGTH 4

class CINWaitSplash : public QWidget
{
Q_OBJECT

public:
CINWaitSplash(QWidget * parent = 0, Qt::WindowFlags f = Qt::SplashScreen|Qt::WindowStaysOnTopHint);

void Init();
void Start();
void Stop();

protected:
void paintEvent(QPaintEvent *);
void InitTable();

private slots:
// Table Pattern Algorithms
void FillTable_SnakePattern();
//void FillTable_RandomPattern();
//void FillTable_BoxPattern();

private:
Ui::SplashForm ui;

QTimer* m_timerMain;

int m_aiCellTable[COLUMNSIZE][ROWSIZE];
};

#endif


As for an event loop... I would have to say no because I am not sure what an event loop is. It is strange because if I turn the timers setInterval(100) to start(100) it will trigger... but after I run my Start() method from a function in my MainWindow it stops... and obviously stops on my Stop() method. So I know the connection is setup. I must be missing something fundamental.

wysota
14th December 2006, 15:14
What do you do after you call Start()? If you don't have an event loop running (either by calling QDialog::exec() or QApplication::exec() or reapeating QApplication::processEvents() calls) timers won't work.

bpetty
14th December 2006, 23:36
Interesting...

This is what I am doing.
I have a class that contains a pointer to my MainWindow and my Splash Screen Widget.
There I create a "singleton" instance of it that my class that can be used in my MainWindow's class. So inside a method of my MainWindow I am calling something like this:



void CINMainWindow::Search()
{
INMyApp()->INWaitSplash()->Start();
CINTimer::Sleep(1000); // Something meaningful would be done here
INMyApp()->INWaitSplash()->Stop();
}


So I am calling Start() and Stop() to my splash screen class from any where I want.

wysota
15th December 2006, 00:51
It doesn't have any chance to work then. If you want to use timers, you have to call QApplication::exec() before or right after Start() and do the rest as small steps triggered by another timer with timeout set to 0, more or less like so:

void MyClass::init1(){
//...
QTimer::singleShot(0, this, SLOT(init2()));
}

void MyClass::init2(){
//...
QTimer::singleShot(0, this, SLOT(init3()));
}

// ...

QTimer::singleShot(0, &MyObjectOfMyClass, SLOT(init1()));
return app.exec();

Timers can only timeout() when the control is in the event loop, so having a single long operation won't allow them to be triggered as well. You either have to use QApplication::processEvents() or use 0-timeout timers like on the example above.