weevil
10th June 2010, 05:21
I'm making a minesweeper type game. My approach was to create a Board class containing a QGridLayout of rows and columns of mine widgets (think 16x30 like windows minesweeper for example). MouseMoveEvents are easily handled by setting setMouseTracking to true in the mine widget, but I ran into trouble trying to handle mouse presses and releases. For example, if the player clicks and holds on one mine and moves the mouse, that mine object receives a mouse press and move event, but when the mouse moves on to other mines, the event data (edit: and object data) is still relative to the initial mine. I want to somehow end each event as it passes on to a new widget, and propagate the original event to the new widget.
I handled this in a Rube Goldberg-esque fashion by computing the row and column of each widget from the initial object event's global position and the fixed size of each mine widget relative to the parent widget like so:
int boardOriginX = parentWidget()->mapToGlobal( QPoint(0, 0) ).x() + Board::margins;
int boardOriginY = parentWidget()->mapToGlobal( QPoint(0, 0) ).y() + Board::margins;
int currentRow = (event->globalY() - boardOriginY) / Board::mineSize;
int currentCol = (event->globalX() - boardOriginX) / Board::mineSize;
and then setting up a Board public function
Mine* Board::getMine( int row, int column )
to get the current mine under the mouse in each event handler. But this has the sideeffect that I'm doing a lot of higher level game handling inside the mouse event handlers of a single mine widget.
This seems really sloppy allowing public access to private data (lol) and involves a lot of annoying and convoluted bounds checking and behind the scenes tracking of changing margins and sizes and number of mines to get the calculations right. Tell me there's an easier way? I wish there was a QMouseEvent member function that returned the current widget under the mouse, but that'd be too easy amirite?
I handled this in a Rube Goldberg-esque fashion by computing the row and column of each widget from the initial object event's global position and the fixed size of each mine widget relative to the parent widget like so:
int boardOriginX = parentWidget()->mapToGlobal( QPoint(0, 0) ).x() + Board::margins;
int boardOriginY = parentWidget()->mapToGlobal( QPoint(0, 0) ).y() + Board::margins;
int currentRow = (event->globalY() - boardOriginY) / Board::mineSize;
int currentCol = (event->globalX() - boardOriginX) / Board::mineSize;
and then setting up a Board public function
Mine* Board::getMine( int row, int column )
to get the current mine under the mouse in each event handler. But this has the sideeffect that I'm doing a lot of higher level game handling inside the mouse event handlers of a single mine widget.
This seems really sloppy allowing public access to private data (lol) and involves a lot of annoying and convoluted bounds checking and behind the scenes tracking of changing margins and sizes and number of mines to get the calculations right. Tell me there's an easier way? I wish there was a QMouseEvent member function that returned the current widget under the mouse, but that'd be too easy amirite?