PDA

View Full Version : mousePressEvent & mouseReleaseEvent question



MarkoSan
6th December 2009, 10:29
Hi to all!

I have a tiny problem regarding mousePressEvent & mouseReleaseEvent: Once I click a mouse button, mousePressEvent is called and once I release it mouseReleasedEvent is called. That works perfectly, but let's say I hold mouse button for half a second. After half a second, I want that mousePressEvent is ignored (I still HOLD mouse button!) and mouseReleaseEvent is called. After that normal event loop is continued. How do I achieve that, please help me!

Sincerely,
Marko

wysota
6th December 2009, 11:02
There is no way to do this. You can forge mouseReleaseEvent() but when you release the mouse, another mouse event will be posted. mouseMoveEvent() will also continue being called as you drag the mouse. Maybe you should say what you need this functionality for?

MarkoSan
6th December 2009, 11:11
Well, here is the task that needs to be done: On my graphics scene I have several ProxyWidgets. If I click on one of the widgets, the "selected" widget gets zoomed in. If I click again same (zoomed in) proxy widget, the proxy gets zoomed out. So far, so good :D. But here is the catch that needs to be impleneted and I simply do not know how to do it: If I press mouse on any of this proxy widgets, it zooms in and if I STILL HOLD the mouse button, for instance, 500ms, I must get zoomed out and event loop continues. So, if I click on window it gets zoomed in and another click zooms it out - that works. But If i hold mouse button, it zooms in, but how then zooms out after 500ms and event loop normally continues?

wysota
6th December 2009, 11:23
Don't treat mouse events as the basis for your functionality but just means to trigger it. If you have a zoomIn() and zoomOut() methods, you can call them from your event handlers. Then you can use a timer that will call zoomOut() 500ms after mousePressEvent has been handled (provided the timer is not canceled by releasing the mouse).

MarkoSan
6th December 2009, 18:44
Don't treat mouse events as the basis for your functionality but just means to trigger it. If you have a zoomIn() and zoomOut() methods, you can call them from your event handlers. Then you can use a timer that will call zoomOut() 500ms after mousePressEvent has been handled (provided the timer is not canceled by releasing the mouse).

But mouse event ARE basis for my functionality, its the same if I call method or call animation after 500ms, it does not work!

squidge
6th December 2009, 19:01
Define "does not work".

Mouse events are meant for one purpose only - to represent the state of the mouse. You should not be trying to put additional fake events into the queue to control your application. If you want your application to do something after 500ms of holding down the mouse, then put that into your application via a timer that is triggered by a mouse press.

MarkoSan
6th December 2009, 19:04
Well, I mean, it is not important if I call method from event handler or handle code in evenhandler, it's same s....!

MarkoSan
7th December 2009, 05:06
Define "does not work".

Mouse events are meant for one purpose only - to represent the state of the mouse. You should not be trying to put additional fake events into the queue to control your application. If you want your application to do something after 500ms of holding down the mouse, then put that into your application via a timer that is triggered by a mouse press.

AAAA, thanks! So you mean, inside mousePress event handler I create timer and start it and then I connect timeout() signal to zoomOut() method/slot? So, I also setup a state of window (i.e. WindowZoomState=ZOOM_IN) and in mouseRelease event handler I check the state. If the state is NOT ZOOM_IN then i zoomOut()? Thanks, will try!

MarkoSan
8th December 2009, 02:06
Well, I did following:
void WidgetProxy::mousePressEvent (QGraphicsSceneMouseEvent * event)
{
scene()->setActiveWindow(this);

// sets up timer
QTimer mouseButtonPressTimer(this);
mouseButtonPressTimer.setSingleShot(true);
mouseButtonPressTimer.setInterval(PRESS_DURATION/*500*/);
mouseButtonPressTimer.connect(&mouseButtonPressTimer,
SIGNAL(timeout()),
this,
SLOT(transferMerchandiseToOrderCart()));
mouseButtonPressTimer.start();

if(m_ZoomState==ZOOM_OUT)
{
mousePressEventTime()->start(); // sets current time to timer

emit zoomTransition(ZOOM_IN);
}
else
{
emit zoomTransition(ZOOM_OUT);
}
}

void WidgetProxy::transferToOrderCart()
{
// drops merchandise into order
emit zoomTransition(ZOOM_OUT); // unselects merchandise
}, but transferToOrderCart() never gets called. Why??

JohannesMunk
8th December 2009, 04:09
Try:



void WidgetProxy::mousePressEvent (QGraphicsSceneMouseEvent * event)
{
scene()->setActiveWindow(this);

// sets up timer
QTimer* mouseButtonPressTimer = new QTimer(this);
mouseButtonPressTimer->setSingleShot(true);
mouseButtonPressTimer->setInterval(PRESS_DURATION/*500*/);
mouseButtonPressTimer->connect(mouseButtonPressTimer,
SIGNAL(timeout()),
this,
SLOT(transferToOrderCart()));
mouseButtonPressTimer->start();

if(m_ZoomState==ZOOM_OUT)
{
mousePressEventTime()->start(); // sets current time to timer

emit zoomTransition(ZOOM_IN);
}
else
{
emit zoomTransition(ZOOM_OUT);
}
}

void WidgetProxy::transferToOrderCart()
{
// drops merchandise into order
emit zoomTransition(ZOOM_OUT); // unselects merchandise
}


Your destination slot was wrong. Created the timer as a pointer.. because I'm not sure what happens, if it goes out of scope otherwise..

HIH

Johannes

MarkoSan
8th December 2009, 04:32
Hmm, now it works. but I have a leakage here, I think it is not good to to create timer every time mouse press is handled without deleting it! And now the window iz zoomed out regardless of holding the mouse button for PRESS_DURATION (which is ok) or just clicking on window. I need following functionality:


if the mouse button is clicked on window, the window get zoomed in until the mouse button is clicked again (the window iz zoomed in because of showing some info inside it)
if the mouse button is HELD down for a time of PRESS_DURATION [ms], the windows is zoomed out automaticly (the window was selected and info inside window has been transferred to some other object, after transfer the window is "deselected and is zoomed out)

wysota
8th December 2009, 10:51
Geez man... an example follows:


class MyWidget : public QWidget {
Q_OBJECT
public:
MyWidget(...) : QWidget(...) {
m_zoomOutTimer.setInterval(500);
m_zoomOutTimer.setSingleShot(true);
connect(&m_zoomOutTimer, SIGNAL(timeout()), this, SLOT(zoomOut()));
}
public slots:
void zoomOut() { zoomOut(currentItem); }
void zoomIn() { ... }
protected:
void mousePressEvent(...) { zoomIn(); m_zoomOutTimer.start(); }
void mouseReleaseEvent(...) {
if(!m_zoomOutTimer.isActive()) return;
m_zoomOutTimer.stop();
zoomOut();
}
private:
QTimer m_zoomOutTimer;
... currentItem;
};

MarkoSan
9th December 2009, 07:26
Geez man... an example follows:


class MyWidget : public QWidget {
Q_OBJECT
public:
MyWidget(...) : QWidget(...) {
m_zoomOutTimer.setInterval(500);
m_zoomOutTimer.setSingleShot(true);
connect(&m_zoomOutTimer, SIGNAL(timeout()), this, SLOT(zoomOut()));
}
public slots:
void zoomOut() { zoomOut(currentItem); }
void zoomIn() { ... }
protected:
void mousePressEvent(...) { zoomIn(); m_zoomOutTimer.start(); }
void mouseReleaseEvent(...) {
if(!m_zoomOutTimer.isActive()) return;
m_zoomOutTimer.stop();
zoomOut();
}
private:
QTimer m_zoomOutTimer;
... currentItem;
};
Well, geez man, that example (thanks for it), BUT IT DOES NOT WORK as it should. Now the windows zooms out either is press mouse button once (WRONG!) either i hold the mouse button (OK).

wysota
9th December 2009, 08:55
This is just an example of a concept of using a timer, adjust it to your needs. I'm sure you can do that after writing 585 posts in this forum. If you just blindly copy code pasted on the forum and expect it to do exactly what you need it to do then probably you should stop doing that and start thinking on your own.