Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Program forgets class and struct memory locations in mousePressEvent, but I can't figure out why
QtWS25 Last Chance

Program forgets class and struct memory locations in mousePressEvent, but I can't figure out why

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 920 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • NeptefreN Offline
    NeptefreN Offline
    Neptefre
    wrote on last edited by
    #1

    I'm having a problem with a board game I've been creating, which has me frustrated.

    It's a board game, where the board is a QGridLayout. Each square of the grid is a class I've called "squareGraphic" (defined in graphics.h), which is a kind of QLabel. squareGraphic contains a various variables, as well as functions and a pointer to a 'position' struct (defined by me in board.h). It also contains a QMouseEvent.

    The board in the game logic is a 3D array of position structs. Each position struct contains two squareGraphic widgets in it - one is the default value of the widget (when no piece is on the square), and the other is the value to be displayed. At the beginning, these point to the same address (I should have made only one squareGraphic widget in each struct and made a variable in squareGraphic that stores the square's default image, which I do intend to; but for now this is what I'm using).

    Note that each squareGraphic contains a pointer to a position struct, which should be the struct that contains that squareGrahpic e.g. if "exampleSquareGraphic" is a squareGraphic in a position struct called "examplePosition", then "exampleSquareGraphic" would contain a pointer to "examplePosition".

    Ultimately I want the user to click on a square (i.e. a squareGraphic), then have the program pass what square was clicked to the game logic, then have the appropriate squareGraphic on the board change what image it shows correspondingly.

    The board initialises just fine, but when I click on a squareGraphic, it seems to forget the value of the struct contained in the squareGraphic. It should be a simple memory problem, but I can't figure out why it's happening. I'll post some code then explain what I've been trying to do.

    Here's how I've defined squareGraphic:

    class squareGraphic : public QLabel
    {
        Q_OBJECT
    public:
    
        explicit squareGraphic(struct position * squarePosition, class gameData * data, QLabel *parent = 0);
        explicit squareGraphic(QLabel *parent = 0);
       ~squareGraphic();
    
    public:
        unsigned int arrayXCoord;
        unsigned int arrayYCoord;
        unsigned int arrayLayNum;
        struct position * thisPosition;
        class gameData * gameData;
        void squareClicked();
        void setCoords(unsigned int layNum, unsigned int XCoord, unsigned int YCoord);
        bool tokenCheck;
    
    protected:
         void mousePressEvent(QMouseEvent *);
    
    signals:
        void clicked();
    
    };
    

    Here's my definition of the 'position' struct:

    struct position
    {
        posType type;
        posColour colour;
        unsigned int mlinStatus;
        squareGraphic * locImg;
        squareGraphic * defaultImg;
        int xCoordWidget;
        int yCoordWidget;
        unsigned int arrayLayNum;
        unsigned int arrayXCoord;
        unsigned int arrayYCoord;
    
        void setCoords(unsigned int layNum, unsigned int XCoord, unsigned int YCoord);
        bool placePiece(enum posColour newToken);
    };
    

    Here's how the squareGraphic widgets and their functions are initialised and defined:

    squareGraphic::squareGraphic(struct position * squarePosition, class gameData * data, QLabel *parent)
        : QLabel(parent)
    {
        tokenCheck = true;
        thisPosition = squarePosition;
        gameData = data;
    
    }
    
    squareGraphic::squareGraphic(QLabel *parent)
        : QLabel(parent)
    {
        tokenCheck = false;
    }
    
    squareGraphic::~squareGraphic()
    {
    
    }
    
    void squareGraphic::setCoords(unsigned int layNum, unsigned int XCoord, unsigned int YCoord)
    {
    
        arrayLayNum = layNum;
        arrayXCoord = XCoord;
        arrayYCoord = YCoord;
    
    }
    
    void squareGraphic::mousePressEvent(QMouseEvent *)
    {
        if(tokenCheck == true)
        {
    
            //std::cout << arrayLayNum << std::endl;
            //std::cout << thisPosition->colour << std::endl;
            // gameData->displayBoard();
            // gameData->placePiece(arrayLayNum, arrayXCoord, arrayYCoord, blackToken);
            emit clicked();
        }
    
    

    Now here's what's confusing me. If I move "std::cout << this->colour << std::endl;" into the function where the board is initialised ("gameData::initBoard()", in board.cpp), it prints the correct values, so I know it's getting initialised. If I move the same expression into "squareGraphic::setCoords()" (ran during the initialisation) in also prints everything correctly. However, the same function in "squareGraphic::mousePressEvent()" prints non-nonsensical memory values. Placing "std::cout << arrayLayNum << std::endl;" in "squareGraphic::mousePressEvent()" prints the correct values.

    So the widget is forgetting the value of the struct but remembering the unsigned ints. I also added "gameData->displayBoard()" (gameData is a class that contains all the data in the program, and displayBoard() prints the board in the command line (used for testing for I started using Qt)) to "squareGraphic::mousePressEvent)", but this also prints nonsensical values. Placing "gameData.displayBoard()" in main.cpp after the initialisation of the board prints the correct values.

    This is really confusing me. It's as if the program is correctly initialising everything, but is only forgetting classes and structs (and nothing else) in squareGraphic::mousePressEvent() (and nowhere else).

    The only function currently being used in game.cpp is the initialisation of the gameData class:

    gameData::gameData()
    {
    
        gameStatus = placing;
        blackPieces.piecesOnBoard = 0;
        blackPieces.piecesUnplaced = numPieces;
        blackPieces.piecesTaken = 0;
        whitePieces.piecesOnBoard = 0;
        whitePieces.piecesUnplaced = numPieces;
        whitePieces.piecesTaken = 0;
    
        tokenImage.blackTokenMap = new QPixmap("resources/blackToken.jpg");
        tokenImage.whiteTokenMap = new QPixmap("resources/whiteToken.jpg");
        tokenImage.emptyTokenMap = new QPixmap("resources/blankSquare.jpg");
        tokenImage.whiteTokenMlinMap = new QPixmap("resources/whiteTokenMlin.jpg");
        tokenImage.blackTokenMlinMap = new QPixmap("resources/blackTokenMlin.jpg");
        tokenImage.horizontalLineMap = new QPixmap("resources/horizontalLine.jpg");
        tokenImage.verticalLineMap = new QPixmap("resources/verticalLine.jpg");
        tokenImage.cornerBottomLeftMap = new QPixmap("resources/cornerBottomLeft.jpg");
        tokenImage.cornerBottomRightMap = new QPixmap("resources/cornerBottomRight.jpg");
        tokenImage.cornerTopLeftMap = new QPixmap("resources/cornerTopLeft.jpg");
        tokenImage.cornerTopRightMap = new QPixmap("resources/cornerTopRight.jpg");
        tokenImage.intersectionBottomMap = new QPixmap("resources/intersectionBottom.jpg");
        tokenImage.intersectionTopMap = new QPixmap("resources/intersectionTop.jpg");
        tokenImage.intersectionBottomMap = new QPixmap("resources/intersectionBottom.jpg");
        tokenImage.intersectionLeftMap = new QPixmap("resources/intersectionLeft.jpg");
        tokenImage.intersectionRightMap = new QPixmap("resources/intersectionRight.jpg");
        tokenImage.intersectionMiddleMap = new QPixmap("resources/intersectionMiddle.jpg");
        initBoard();
        initBoardWidget();
    }
    

    initBoard() and initBoardWidget() are defined in board.cpp. They're too long to copy here, but essentially they just initialise the values in gameData.

    Here's my mainwindow.cpp:

    MainWindow::MainWindow(QWidget *parent)
        : QWidget(parent)
    {
       class gameData gameData;
       QHBoxLayout * appBox = new QHBoxLayout;
       setLayout(appBox);
       appBox->addWidget(gameData.boardWidget);
    
    }
    

    And here's my main.cpp:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
    
    
    
        w.show();
    
        return a.exec();
    }
    

    There are other functions (mainly in game.cpp) which handle the game logic, but most haven't been applied to the actual program yet, so are irrelevant to this problem.

    The full program can be found here:
    https://github.com/Matulin/MlinConsole

    Sorry for the long post. I hope you can help me with this problem.
    Thanks in advance.

    1 Reply Last reply
    0
    • sneubertS Offline
      sneubertS Offline
      sneubert
      wrote on last edited by
      #2

      Hi Neptefre,
      in mainwindow.cpp you create a local! object on the stack with class gameData gameData;. This object is gone if the constructor of mainwindow end.
      If you create a heap object like this

      MainWindow::MainWindow(QWidget *parent)
          : QWidget(parent)
      {   
         //class gameData gameData;
         gameData *gameData2 = new gameData;
         QHBoxLayout * appBox = new QHBoxLayout;
         setLayout(appBox);
         //appBox->addWidget(gameData.boardWidget);
         appBox->addWidget(gameData2->boardWidget);
      }
      

      the squareGraphic::mousePressEvent in prints out some plausible values

      NeptefreN 1 Reply Last reply
      2
      • sneubertS sneubert

        Hi Neptefre,
        in mainwindow.cpp you create a local! object on the stack with class gameData gameData;. This object is gone if the constructor of mainwindow end.
        If you create a heap object like this

        MainWindow::MainWindow(QWidget *parent)
            : QWidget(parent)
        {   
           //class gameData gameData;
           gameData *gameData2 = new gameData;
           QHBoxLayout * appBox = new QHBoxLayout;
           setLayout(appBox);
           //appBox->addWidget(gameData.boardWidget);
           appBox->addWidget(gameData2->boardWidget);
        }
        

        the squareGraphic::mousePressEvent in prints out some plausible values

        NeptefreN Offline
        NeptefreN Offline
        Neptefre
        wrote on last edited by Neptefre
        #3

        @sneubert Thanks for the reply! It seems to have fixed the problem.

        I feel like an idiot now for not realising it was something so simple. It's been driving me mad, and it turns out I wasn't even looking in the right place!

        I'll credit you with a comment in the program.

        1 Reply Last reply
        0
        • sneubertS Offline
          sneubertS Offline
          sneubert
          wrote on last edited by
          #4

          You´r welcome. Don´t be angry with yourself too much. Me and probably every other had for sure some similar issue while writing code. Sometimes if you´r deep inside it´s hard to see the obvious. That´s what this forum is for.

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved