I am working on a c++ CLI application and am having some difficulty with events. I am wondering if I can get events to fire while the mouse button is clicked. For example, I am wanting to check whether or not the mouse has moved to the next square over only if they have the mouse clicked in. Meaning if they click on square 1 they should be able to hold that click and move the square 2 and my program recognize this.
I have run a number of different events on the mouse, including the "Click" event, but the neither the hover, mouse enter, or mouse down event get triggered while the button is pressed. The "MouseClick" event, which does the same. I tried using just the mouseDown event, but this does not let another mouseDown event, mouse enter, or hover event fire.
Short of checking mouse position I do not know what I can do. I would like to not have to do mouse position checking.
If anyone has any ideas, they would be greatly appreciated.
Clearly you'll want to pay attention to the MouseMove event so you can see the mouse moving into another square. Roughly:
void panel1_MouseMove(Object^ sender, MouseEventArgs^ e) {
if ((e->Button & System::Windows::Forms::MouseButtons::Left) ==
System::Windows::Forms::MouseButtons::Left) {
int square = MapPosToSquare(e->Location);
if (square != currentSquare) {
currentSquare = square;
OnSquareClicked(currentSquare);
}
}
}
If these "squares" are actually controls then you have a different problem. You have to set the control's Capture property to false in the MouseDown event handler so it doesn't capture the mouse.
Related
What event do I need to write in my wxWidgets program so that I can track mouse dragging.
I mean hold down the left mouse button and track the movement while it is pressed.
Perhaps surprisingly, this is not such a simple task. You may look at the implementation of wxMouseEventsManager to see an example of working code doing it, but the main point is that you need to capture the mouse on button press, in order to follow its movement even if it exits the window, and then you need to also react to wxEVT_MOUSE_CAPTURE_LOST events to know when the capture is forcibly broken.
Bind(wxEVT_MOTION, [&](wxMouseEvent& event) {
if (event.Dragging()) {
if (event.LeftIsDown()) {
// code
}
}
});
I am trying to catch the mouse motion when I hold the mouse middle button. The goal is to implement a rotation feature in an stl viewer.
I found the event mask BUTTON2_MOTION_MASK. But I have a hard time figuring out which signal catches it.
Here's the two line I use to create and hook the event. These two line are inside a GtkApplicationWindow Constructor.
glWidget.add_events(Gdk::BUTTON2_MOTION_MASK);
glWidget.signal_motion_notify_event().connect(sigc::mem_fun(*this,&mainWindow::rotate));
Here's the function I am trying to connect.
bool mainWindow::rotate(GdkEventMotion* motion_event)
{
cout<<"test"<<endl;
}
Am I using the correct method? The code does not react when I hold the middle mouse button and move mouse.
I managed to get glArea widget to react to scrolling this way.
glWidget.add_events(Gdk::SMOOTH_SCROLL_MASK);
glWidget.signal_scroll_event().connect(sigc::mem_fun(*this,&mainWindow::zoom));
the function I connected:
bool mainWindow::zoom(GdkEventScroll *eventScroll)
{
cout<<"test"<<endl;
return true;
}
I figured it out. You need to both add the Gdk::Button1_MOTION_MASK and the Gdk::BUTTON_PRESS_MASK.
glWidget.add_events(Gdk::Button1_MOTION_MASK | Gdk::BUTTON_PRESS_MASK);
This will catch the signal when the left mouse button is clicked and positioned on the widget.
BUTTON2_MOTION_MASK will require that 2 button are pressed. For some reason, it's only the left mouse button(I want the middle button).
i'm developing a Qt application, I know that there is a wheelEvent to get the wheel's state, but I can't find how to know if the wheel is pressed.
thanks !
The wheel event set up the buttons which are being pressed. It also set the keyboard modifier keys which are pressed (eg. SHIFT, CRTL).
void MyWidget::wheelEvent ( QWheelEvent * event )
{
if(event->buttons() & Qt::MiddleButton != 0)
{
//the mid button is being pressed. handle.
}
}
Here is a list of possible buttons. They are set as flags, i.e Qt::LeftButton | Qt::RightButton
Edit:
The wheel is associated by default to the middle button. The wheel can move without an associated button in the wheel event. For instance, on chrome browsers moving the wheel scrolls. Pressing the wheel will change the cursor on the screen as well as the behavior of the wheel(try it).
If you have a weird mouse with a wheel and a middle button:
Pressing the middle button will generate a MouseEvent with Qt::MiddleButton
Pressing the wheel button will generate a WheelEvent with Qt::MiddleButton.
Look in the documentation of QMouseEvent. Catch that event and watch out for the third mouse button.
If you are not interested in an event but the state of the button you also may be interested in QGuiApplication::mouseButtons().
I'm creating an application that provides a visual representation of nodes and lines connecting them together. Both nodes and lines are represented by custom QWidgets, WidgetNode and WidgetLine, say.
I've implemented WidgetLine as a transparent widget that is large enough to contain the start and end point of the line, and a custom function to draw the line itself.
I would like it so that if the user clicks on or right next to the line then the WidgetLine receives focus, but if they click further away from the line (but still over the rectangular area covered by WidgetLine's geometry) then the click is completely ignored by WidgetLine and passed on to the widget below.
I first tried doing this with a custom focusInEvent() function on WidgetLine, but found the mouse clicks weren't propagating below. I then tried setting the focus policy to Qt::NoFocus and using a custom mousePressEvent() using setFocus() to manually set the focus when appropriate, but the mouse events are still not being propagated to widgets above even when I call ignore() on them.
Finally, I've tried installing an event filter to reject mouse events, with this event filter function
bool WidgetLineFilter::eventFilter(QObject* object, QEvent* event)
{
assert(object == mCord);
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* e = dynamic_cast<QMouseEvent*>(event);
assert(e);
if (e)
{
QPoint mouseRelativeToParent = mCord->mapToParent(e->pos());
// calculate distance of mouse click to patch cord
QLineF line(mCord->line());
float distance = distanceFromPointToLine(QVector2D(line.p1()), QVector2D(line.p2()), QVector2D(mouseRelativeToParent));
qDebug() << distance;
const float distanceThreshold = 2.f;
if (distance < distanceThreshold)
{
qDebug() << "consuming mouse click for focus";
mCord->setFocus(Qt::MouseFocusReason);
return true;
}
else{
qDebug() << "mousepressevent too far for focus";
return QObject::eventFilter(object, event);
}
}
}
return false;
}
But this still does not propagate the mouse events to the parent on the "mousepressevent too far for focus" case. I've also tried returning false and true from here, and calling ignore on e but the widgets below are not receiving the click.
(NB the above approaches do work in the sense that WidgetLine only gets focus at the right time, it's just the widgets below that aren't receiving the press events when it doesn't get focus.)
Any ideas on how to fix this?
Store the mouse pos in a global var. Have all of your widgets have enter/leave events like the following and use that to check what widget you're in / near when you run the func.
void QGLWidget::enterEvent(QEvent *)
{
setFocus();
}
void QGLWidget::leaveEvent(QEvent *)
{
clearFocus();
}
In the end, I created an event filter to selectively intercept mouse events and installed it on the base window and recursively on every single child widget of the base window (installing it on new child widgets when they are created). This filter calls the base window with each mouse press event which then iterates through each WidgetLine, testing if they should be selected by this mouse press and setting focus on them if they should. If they all test false then the filter releases the event, otherwise the filter consumes it.
WidgetLine's are then set to be transparent for mouse events with
setAttribute(Qt::WA_TransparentForMouseEvents);
It's messier than it ought to be to achieve this but does the trick.
I'm reading about the GetCapture() function , which is part of the mfc.
I'm still unclear as to what it does, as well as what it means to capture the mouse , as it says here:
http://msdn.microsoft.com/en-us/library/dxa5eaaa(v=vs.80).aspx
in my book it's used in this way:
void CSketcherView::OnLButtonUp(UINY nFlags, CPoint point)
{
if(this == GetCapture())
ReleaseCapture(); // Stop capturing mouse messages
// ... add information to document
}
So what does GetCapture() return? and what does "capturing" the mouse mean?
As a concrete example for the purpose of mouse capture:
Take a window with two pushbuttons. Click on one of them and keep the mouse button held down. Now drag the mouse cursor over to the second pushbutton and release the mouse button. The first pushbutton will receive a WM_LBUTTONUP message, but the second won't, even though the mouse cursor is on top of it.
When that first pushbutton received the WM_LBUTTONDOWN message, it captured the mouse. While a window is capturing the mouse, it guarantees that it will receive all subsequent mouse events (particularly the WM_LBUTTONUP message), even if the mouse has been dragged outside of its window bounds. This is important so that it can match button-down to button-up messages and maintain proper state. It's also important for usability (if you click on one button and accidentally move away to another button, you neither want to trigger the first nor the second button).
Capturing the mouse usually means you will stil get Mouse events even when the mouse cursor position is outside the bounds of your window
The GetCapture function simply returns the current window that has the mouse capture.