0

Problems description:

  • I am designing a player class. This player class can either inherit from QGraphicsRectItem OR can have a QGraphicsRectItem member (composition).
  • When the player inherits from QGraphicsRectItem, I can implement a keyPressEvent moving the player to the right or to the left.
  • When the player has a QGraphicsRectItem member, I can't implement the keyPressEvent moving the player to the right or to the left.

code:

A] Inheritance case:

.h file:

#ifndef PLAYER_H
#define PLAYER_H


#include <QGraphicsItem>
#include <QGraphicsRectItem>
#include <QKeyEvent>
#include <QDebug>
#include <QPainter>

class Player : public QObject, public QGraphicsRectItem{
    Q_OBJECT //Macro


public:
    Player();
    void keyPressEvent(QKeyEvent * event);

};
#endif // PLAYER_H

.cpp file:

#include "Player.h"


Player::Player(){
    setRect(0, 0, 100, 100);
    setBrush(Qt::black);
}


void Player::keyPressEvent(QKeyEvent * event)
{
    qDebug() << "Player senses left arrow and right arrow presses.";
    if(event->key() == Qt::Key_Left){
        if(pos().x() > 0)
            setPos(x()-50, y());
    } else if (event->key() == Qt::Key_Right){
        if(pos().x() + rect().width() < 1200)
            setPos(x()+50, y());
    }
}

main:

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>

#include "Player.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //has a session
    QGraphicsScene * scene = new QGraphicsScene();;
    //has a view
    QGraphicsView * view = new QGraphicsView(scene);;
    //has a player
    Player * player = new Player();;


    //Add player to a session
    scene -> addItem(player);


    //Make player focusable
    player->setFlag(QGraphicsItem::ItemIsFocusable);
    player->setFocus();


    //set coordinates
    view->setFixedSize(1200, 600);
    scene->setSceneRect(0, 0, 1200, 600);
    player->setPos(view->width()/2-((player->rect().width())/2), view->height()-player->rect().height());

    // a view is invisible by default, you have to show it
    view->show();

    return a.exec();
}

B] Composition case:

.h file:

#ifndef PLAYER_H
#define PLAYER_H

#include <QGraphicsItem>
#include <QGraphicsRectItem>
#include <QKeyEvent>
#include <QDebug>
#include <QPainter>


class Player : public QObject{
    Q_OBJECT //Macro!

public:
    QGraphicsRectItem * curRect;
    Player();
    void keyPressEvent(QKeyEvent * event);

};

#endif // PLAYER_H

.cpp:

#include "Player.h"

Player::Player(){
    curRect = new QGraphicsRectItem;
    curRect->setRect(0, 0, 100, 100);
    curRect->setBrush(Qt::black);
}


void Player::keyPressEvent(QKeyEvent * event)
{
    qDebug() << "Player senses left arrow and right arrow presses.";
    if(event->key() == Qt::Key_Left){
        if(curRect->pos().x() > 0)
            curRect->setPos(curRect->x()-50, curRect->y());
    } else if (event->key() == Qt::Key_Right){
        if(curRect->pos().x() + curRect->rect().width() < 1200)
            curRect->setPos(curRect->x()+50, curRect->y());
    }
}

main:

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>

#include "Player.h"


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //has a session
    QGraphicsScene * scene = new QGraphicsScene();;
    //has a view
    QGraphicsView * view = new QGraphicsView(scene);;
    //has a player
    Player * player = new Player();;


    //Add player to a session, set its initial position and color
    scene -> addItem(player->curRect);


    //Make player focusable
    player->curRect->setFlag(QGraphicsItem::ItemIsFocusable);
    player->curRect->setFocus();


    //set coordinates
    view->setFixedSize(1200, 600);
    scene->setSceneRect(0, 0, 1200, 600);
    player->curRect->setPos(view->width()/2-((player->curRect->rect().width())/2), view->height()-player->curRect->rect().height());

    // a view is invisible by default, you have to show it
    view->show();

    return a.exec();
}

The QDebug confirms the above problem. I wonder why is this? It is very critical that I use composition rather than inheritance, because the player will have other components and I want to avoid multiple inheritance. Any help with troubleshooting is greatly appreciated.

Ciao.

mansanto
  • 360
  • 4
  • 16
  • Why do you think that the player class in the composition will have the keyPressEvent event? – eyllanesc Feb 04 '18 at 21:11
  • Do you understand the characteristics of inheritance and composition? – eyllanesc Feb 04 '18 at 21:12
  • I am a beginner in OOP/Qt. My current understanding level of inheritence/composition is reflected in the provided code. I am definitely missing on something and this is why I solicit feedback/hints from other members of this community. – mansanto Feb 04 '18 at 21:22
  • Why player inherits from QObject? The first recommendation is to read and understand and just apply, do not go in the opposite direction. – eyllanesc Feb 04 '18 at 21:25
  • 1
    Are you aware that `keyPressEvent()` is a `virtual` method? Your issue is actually caused by the lack of knowing basic C++ concepts. I found [SO: Why do we need virtual functions in C++?](https://stackoverflow.com/q/2391679/7478597) regarding this which might help. (It's not intended as replacement for a C++ book.) ;-) – Scheff's Cat Feb 05 '18 at 06:58

0 Answers0