Moving object using keyboard qt - c++

I'm trying to move an object using my arrow keys, but when I launch the app, nothing happens. Do you have an idea on how to fix it ?
#Update : my rectangle only moves once to the left and to the right, but if I use qDebug it recognizes all the times I click left or right, any ideas ?
void MouvementJoueur::keyPressEvent(QKeyEvent *e)
{
switch ( e->key() )
{
case Qt::Key_Left:
rectangle->setPos(x()-10,y());
qDebug() << "You pressed the Key left";
break;
case Qt::Key_Right:
rectangle->setPos(x()+10,y());
qDebug() << "You pressed the Key right";
break;
}
}
Thank you in advance !

Your issue seems to be, that you take position of the parent, and set position of rectangle based on that. This is probably not what you want to do with key presses here. You should set the position like this:
rectangle->setPos(rectangle->x() - 10, rectangle->y());

You can refresh the GUI with the following command
view->processEvents();
and you can debug it. It detect the key press or not.
void MouvementJoueur::keyPressEvent(QKeyEvent *e)
{
if(e->key() == Qt::Key_Left)
{
rectangle->setPos(x()-10,y());
qDebug() << "You pressed the Key x";
}
if(e->key() == Qt::Key_Right)
{
rectangle->setPos(x()+10,y());
qDebug() << "You pressed the Key x";
}
}

Related

How can I make Qt recognize a sequence of keys?

In my current application, I need to make QT close a window by pressing Shift + Eesc or by pressing Esc 3x.
First, I tried Shift + Esc, it went this way
if ((event->key() == Qt::Key_Escape) && (event->key() == Qt::Key_Shift))
{
cout << "test" << endl;
on_close_x_button_clicked();
}
But for some reason, it just doesn't work. I googled it and found something about a QKeySequence but I didn't find any example of how to do it properly. I tried some ways with no success like:
if ((event->key() == Qt::QKeySequence(Qt::Key_Escape + Qt::Key_Shift)))
{
cout << "teste" << endl;
on_close_x_button_clicked();
}
}
But again, no dice. Can someone point me how to proper implement this functionality?
I also could not find anything that allowed me to create an event based on pressing Escape key 3x. Can someone, please, also teach me how to do it?
I also tried using Shortcuts, and it went like this:
LinAdvancedTestWidget::LinAdvancedTestWidget(QWidget *parent,
QObject *event_filter,
SystemEvent *event, int dpi)
: AdvancedTestWidget(parent, event_filter, event) {
(void)dpi;
KeyShiftEsc = new QShortcut(this);
KeyShiftEsc->setKey(Qt::Key_Shift + Qt::Key_Escape);
connect(KeyShiftEsc, SIGNAL(activated()), this, SLOT(slotShortcutShiftEsc()));
}
void LinAdvancedTestWidget::slotShortcutShiftEsc()
{
cout << "Escape LinAdvancedTestWidget" << endl;
on_close_x_button_clicked();
}
But it again, also does not work :/
Shift is a modifier, not a key, as you seem to compare. You would need to write something like this:
if ((event->key() == Qt::Key_Escape) && (event->modifiers() & Qt::Key_Shift))
{
...
}
Also, it is better if you use the QWidget::addAction(...) method as:
QAction *action = new QAction("my action", "Shift+Esc");
myWidget->addAction(action);
You can also set multiple shortcuts on an action:
action->setShorcuts({"Shift+Esc", QKeySequence(Qt::Key_Esc, Qt::Key_Esc, Qt::Key_Esc)});

SDL_KEYUP triggered when key is still down

I am using SDL2 in C++ to create a sprite. However, the SDL_KEYUP is constantly triggered when I am pressing the key.
void update() override {
if(Game::event.type == SDL_KEYDOWN) {
switch(Game::event.key.keysym.sym) {
case SDLK_z:
cout << "key down" << endl;
break;
default:
break;
}
}
if(Game::event.type == SDL_KEYUP) {
switch(Game::event.key.keysym.sym) {
case SDLK_z:
cout << "Key up" << endl;
break;
default:
break;
}
}
}
It's a feature, not a bug. If you hold a key for half a second or so, SDL will start to generate "fake" key-down & key-up events.
This is used primarily for text editing, but is mostly useless otherwise.
Ignore all keyboard events that have event.key.repeat != 0.
Also, if you're writing a game, you might want to use scancodes instead of keycodes (e.g. event.key.keysym.scancode == SDL_SCANCODE_A instead of event.key.keysym.sym == SDLK_a).
Keycodes depend on the current layout, and scancodes don't. Scancodes represent physical key locations. The diffence is noticeable if you use a non-QWERTY layout. (E.g. SDLK_z is always bound to the key that has Z printed on it, while SDL_SCANCODE_W is bound to W on QWERTY and Z on AZERTY.)

keyPressEvent(QKeyEvent *e) does not work for enter key

I am trying to detect when a user presses Enter or Alt+Enter in a QTextEdit. I am doing the following
void contacts::keyPressEvent(QKeyEvent *e)
{
if(ui.TextEdit->hasFocus())
{
//Alt + Enter deection
if ((e->key()==Qt::Key_Return) && (e->modifiers()==Qt::AltModifier))
{
//Alt + Enter pressed
}
//Enter pressed
else if (e->key()==Qt::Key_Return)
{
///Enter was pressed
}
}
}
However this does not detect the enter Key alone. Do you think I should use Event Filter for this ?? What if later on I decide to block a certain key and not have it processed ?

i want to display a message when i click(left or right) on widget in qt

This code is for VLC Media Player. If I move the mouse in fullscreen, the message and the x,y coordinates get displayed. I want to display a message when I click (left or right) on fullscreen. How can I do this? I'm using Qt.
void FullscreenControllerWidget::mouseChanged( vout_thread_t *p_vout, int i_mousex, int i_mousey )
{
bool b_toShow;
/* FIXME - multiple vout (ie multiple mouse position ?) and thread safety if multiple vout ? */
qDebug() << "mouse moved"; //ajay
b_toShow = false;
if ((i_mouse_last_move_x == -1 || i_mouse_last_move_y == -1) ||
(abs( i_mouse_last_move_x - i_mousex ) > 2 ||
abs( i_mouse_last_move_y - i_mousey ) > 2 ))
{
i_mouse_last_move_x = i_mousex;
i_mouse_last_move_y = i_mousey;
qDebug() << "mouse move changed x:" << i_mouse_last_move_x; // ajay
qDebug() << "mouse move changed y:" << i_mouse_last_move_y; // ajay
b_toShow = true;
}
if (b_toShow)
{
/* Show event */
IMEvent *eShow = new IMEvent(FullscreenControlShow_Type, 0);
QApplication::postEvent(this, eShow);
/* Plan hide event */
IMEvent *eHide = new IMEvent(FullscreenControlPlanHide_Type, 0);
QApplication::postEvent(this, eHide);
}
}
There is a special event for mouse clicks.
http://developer.qt.nokia.com/doc/qt-4.8/qwidget.html#mousePressEvent
http://developer.qt.nokia.com/doc/qt-4.8/qwidget.html#mouseReleaseEvent
Did you try implementing those? Btw. mouseChanged is vlc-specific.

How to make keyword to work instantly with no delay in Qt::4.6 (C++)?

OS:: win xp sp3.
Qt:: 4.6
I have class Gameboard in which i have some rectangle.I defined keyPressEvent for that rectangle in order to move him around the screen.Key_A :: rectangle.moveToLeft & Key_D :: rectangle.moveToRight.Problem is that keys work with delay.
When i release one key and press another one it takes some time before that one begin to work.I checked Qt online documentation and now for that effect but dont now how to make those keys to work instantly without delay beetween them?
code snippet:
//in Gameboard class
ship = new QRect(x,y,w,h);
void Gameboard::keyPressEvent(QKeyEvent* event)
{
switch(event->key()) {
case Qt::Key_A :
{
x = x-10;
ship->moveTo(x,y);
break;
}
case Qt::Key_D :
{
x = x+10;
ship->moveTo(x,y);
break;
}
}
}
Put input cursor into any applicable text box and press the 'A' key. What you'll see is once you press the key, letter 'A' will be printed, then there will be a pause, and then first letter 'A' will be quickly followed by many others. That's the way keypress events work. And your program is receiving them exactly like this. First you receive one event when the key is actually pressed, and then after a delay you get a lot of automatically repeated events, in case user wants to enter one character many-many times.
It works perfectly for text input, but in games you usually need smooth movement. If that's the case, you need to move your ship not upon receiving the event, but regularly, for example, on timer event. And you will need to catch both keyPressEvent and keyRelease event and use them to remember what movement keys are currently pressed. So you could for example do this:
struct Ship {
bool is_moving_left, is_moving_right;
QPoint position;
int speed;
...
void timerEvent()
{
if (is_moving_left) position.setX (position.x() - speed);
if (is_moving_right) position.setX (position.x() + speed);
}
...
};
...
void Gameboard::keyPressEvent (OKeyEvent *_event)
{
switch(event->key()) {
case Qt::Key_A :
ship->is_moving_left = true;
break;
case Qt::Key_D :
ship->is_moving_right = true;
break;
}
}
...
void Gameboard::keyReleaseEvent (OKeyEvent *_event)
{
switch(event->key()) {
case Qt::Key_A :
ship->is_moving_left = false;
break;
case Qt::Key_D :
ship->is_moving_right = false;
break;
}
}
Then just make sure Ship::timerEvent() gets called on every timer event in the game.