Reputation: 75
I've a problem with QMouseEvent:
void Gioco::gioco_G1()
{
QMouseEvent *mouse = new QMouseEvent;
bool stato = false;
do
{
if (mouse->KeyPress() == Qt::MouseButton::LeftButton) {
qDebug()<<"entra nell'if";
if (img_mano1G1 -> isUnderMouse()) {giocata_G1 = manoG1[0]; stato = true;}
else if (img_mano2G1 -> isUnderMouse()) {giocata_G1 = manoG1[1]; stato = true;}
else if (img_mano3G1 -> isUnderMouse()) {giocata_G1 = manoG1[2]; stato = true;}
}
} while (stato == false); //repeat until I enter an if
}
I've created a scene and I've inserted some QGraphicsPixmapItem in the scene. Now I want to enter in the "if" when I click on a specified QGraphicsPixmapItem.
For example when I click on img_manoG1 I want to enter in the first "if"
How can I tell the program to stop and wait for the mouse input ?
TI'm new to Qt and it's the first time i use the objects so I make a lot of logical mistake, so using QStateMachine it's a big problem...
It's the only way to do thath ? I try to explain my program:
I want to create a card's game and in the previous version I've used an old graphics library with this sequence of commands:
-> print cards on the scene
-> wait for a mouse input (with a do-while)
-> if(isMouseClick(WM_LBUTTONDOWN))
-> if(mouse position is on the first card)
-> select that card. So i wish to do the same thing with QGraphics.
In this way I tell the program:
-> print cards
-> wait for a mouse event
-> print the card that I've selected with that event.
Now I want to change the program graphics and I've introduced QGraphics. I've created a scene and print all the objects "card" on it so now i want to tell the program:
-> print the object and wait the mouse input
-> if a card is to selected with the left clik
-> print that card in scene, wait 1/2 second and go ahead with the program
The problem is that I use a for
1 to 20 (I must run that 20 times in a match).
I've tried to lauch the program with a random G1 and COM play but the application freeze until the last execution of the for
and I print on the scene only the last configuration of cards.
That is the reason because previously I said I want the program to stop...
It is possible to do without QStateMachine ? Simply telling him: "pause", print this situation, wait for mouse and go ahead ?
Upvotes: 0
Views: 802
Reputation: 98425
Since you create the default-constructed mouse event yourself, why do you expect it to contain any usable data?
To handle events, you must override the relevant event handler virtual method. In your case, you might wish to override the QGraphicsScene::mousePressEvent
in your derived scene class.
How can I tell the program to stop and wait for the mouse input ?
You don't want the program to stop. A stopped program is literally frozen and accepts no user input, it'd be useless. Your while
loop would have that effect - it'd never terminate, since it never accepts any events.
What you want to do is to change the state of the UI so that it implements your "stopped" behavior. What you really want is to react to a mouse click, whenever it happens, iff your UI is in a state where it should accept a mouse click. So, you should design a state machine that represents the states and transitions your program's user interface should take, and then implement that state machine either as an explicit QStateMachine
, or implicitly using the usual "spaghetti" approach of handling various states individually in event handlers, and representing the state as an enum
.
To do this, you'd roughly need to follow these steps:
Decide what UI objects (QWidget
and QGraphicsItem
instances) are involved in the interaction. Anything that needs to change its behavior is involved.
Partition the behavior of your UI into a state machine, at the simplest level into a disjoint set of states (a non-hierarchical machine).
Decide what behavior changes do you wish in each state.
Implement a state variable to represent the current state: either as a configuration of a QStateMachine
, or as an enum
. For QStateMachine
, each state would be a QState
instance. For an enum
, each state would be the value of the enum.
Implement the behavior changes on state transitions. QStateMachine
would allow a more declarative approach, where you say "on entering/leaving this state, change the following properties of objects" and "on receiving this event by that object, do that". An enum
-based implementation requires you to handle the events explicitly by overriding event handlers in QObject
-derived classes.
Read up on the Qt State Machine Framework, it's a good introduction to UML Statecharts and it'll help you to think about the behavior of your UI in a more formalized, disciplined fashion - even if you don't use that particular implementation of the UML Statecharts.
Upvotes: 1