PDA

View Full Version : Serious problem with QGLWidget



al101
26th April 2007, 19:47
Hello

I'm looking to write an opengl based editor using QT but I'm experiencing a problem with QGLWidget. I have implemented a camera class and it moves smoothly when I move it 'programmatically' and from input using the mouseMoveEvent, but when I update the camera using input from keyPressEvent it is erratic and shows what looks like a double image of the previous frame. I've subclassed the QGLWidget and placed it on my main window and tried adding the keyPressEvent function to the opengl widget class and as a function of main window but the same problem remains.

Has anybody else experienced this problem, which I belive is caused by the high number of keyboard events being sent, and know of a way to work around it for smooth keyboard input?

I am currently using version 4.3.0beta/Mingw with QDevelop and have an example program that allows you to switch from one input method to another as a test. It contains all the source code and project file too. The download is available here at http://www.alsprogrammingresource.com/Test.zip

Regards
Alan

wysota
26th April 2007, 20:02
I suggest you start by adding a timer to check for key presses instead of handling them directly in keyPressEvent to get a steady movement. In keyPress/keyRelease events only flag that a key has been pressed or released and then handle the actual change in the timer timeout. Maybe this will be enough to make it work correctly.

al101
26th April 2007, 20:13
Thanks wysota

I'll certainly give that a try. Polling the key press events periodically may be the only work around but I was wondering if it was a common problem with a standard solution. I'll see what happens and post the results if successful.

wysota
26th April 2007, 20:46
"Standard solution" is to use a timer. You're currently using a non-standard one :)

al101
26th April 2007, 21:29
ok, I've added an array of flags to record which keys were pressed:

bool keypress[256];

and changed the keyPressEvent and keyReleaseEvent to:



void MainWindowImpl::keyReleaseEvent( QKeyEvent *e )

{

switch( e->key() )

{

if (keyboardControl)

{

case Qt::Key_W:

case Qt::Key_S:

case Qt::Key_A:

case Qt::Key_D:

case Qt::Key_Q:

case Qt::Key_E:

keypress[e->key()] = false;

break;

}

}

}



void MainWindowImpl::keyPressEvent( QKeyEvent *e )

{

switch( e->key() )

{

if (keyboardControl)

{

case Qt::Key_W:

case Qt::Key_S:

case Qt::Key_A:

case Qt::Key_D:

case Qt::Key_Q:

case Qt::Key_E:

keypress[e->key()] = true;

break;

}
}
}

and changed the time out routine to:


void OGLWidget::timeOutSlot()

{

if (keypress[Qt::Key_W])

camera[currentCamera].Movement_z -= 0.01;



if (keypress[Qt::Key_S])

camera[currentCamera].Movement_z += 0.01;



if (keypress[Qt::Key_A])

camera[currentCamera].Movement_x -= 0.01;



if (keypress[Qt::Key_D])

camera[currentCamera].Movement_x += 0.01;



if (keypress[Qt::Key_Q])

camera[currentCamera].Movement_y -= 0.01;



if (keypress[Qt::Key_E])

camera[currentCamera].Movement_y += 0.01;



updateGL();

}

but the results are still erratic, how would I go about polling key press events using a timer or can you suggest an example or tutorial that I could refer to?

jacek
26th April 2007, 21:57
switch( e->key() )
{
if (keyboardControl)
{
case Qt::Key_W:
...
}
}
In this case "if(keyboardControl)" has no effect, as switch simply jumps to appropriate case clause.

al101
26th April 2007, 22:06
thanks, I noticed this after I had released the test program. It didn't play a part in the problem so I just left it. ;)

wysota
26th April 2007, 22:37
Instead of the array you may want to try QSet<Qt::Key> and possibly also QSet<Qt::KeyboardModifier>. It should give you more flexibility. If not, then I'd like to notice that you're wasting 7 out of 8 bits of each cell in the array which gives a total waste of 224 bytes ;)

al101
26th April 2007, 22:49
ic, good to know :)

On the keyboard input subject I might add that I have been downloading every QT program that displays an QGLWidget that I could find. A prime example of the problem can be seen clearly when viewing the examples of libQGL Viewer available here http://artis.imag.fr/~Gilles.Debunne/QGLViewer/

wysota
26th April 2007, 22:55
Could you be more specific?

al101
26th April 2007, 23:19
Sure, if you download any of the examples on that site and use the arrow keys to move the camera left and right you will see that the problem is very obvious. I simply can't find any application with a QGLWidget with smooth scrolling based on keyboard input.

wysota
27th April 2007, 00:30
Is this smooth enough for you (it rotates instead of scrolling, but the idea remains...)?

al101
27th April 2007, 13:52
Back from sleep, work...

Thanks for the example wysota. I just found that the changes in my third post worked to solve the problem, but I also had to remove the timing routine that I introduced as a fix.

So again, thanks for working with me on this. I'll post the link of a working example or tutorial soon.