PDA

View Full Version : help needed in QMouseEvent



aj2903
14th February 2009, 07:48
i have lineEdit control & 2 Button i.e Enter and Clear
When the User Presses Clear Button for 4 sec or more the text in the lineEdit should be cleared.

I'm not able to capture the pressEvent on the clear button.
Help Needed.

spirit
14th February 2009, 08:18
why do you use events? QPushButton has signal clicked. you can try to use in.

Lykurg
14th February 2009, 08:24
Why ever you want to force the user to press a button 4 seconds, simply subclass QPushButton an implement QWidget::mousePressEvent ( QMouseEvent * event ). (and of course QWidget::mouseReleaseEvent ( QMouseEvent * event ) to measure the time)

Lykurg

talk2amulya
14th February 2009, 08:36
here is how u do it buddy:

first use setMouseTracking(true) for your button class. start a timer when the mousePressEvent comes. set a timeout for 4 seconds on the timer and on slot for timeout(), u can clear the text

void YourButtonClass::mousePressEvent(QMouseEvent* event)
{

if (event->button() == Qt::LeftButton)
{
Timer->start(m_sec);
m_bMouseButtonDown = true;
}

}

void CAutoRepeatButton::mouseReleaseEvent(QMouseEvent* event)
{

if (event->button() == Qt::LeftButton)
{
m_pAutoRepeatTimer->stop();
m_bMouseButtonDown = false;

if (m_pAutoRepeatTimer->interval() == urInterval)
{
urSlot();
}
}
}

this should solve ur problem

aj2903
14th February 2009, 09:17
thanks to all for quick reply.

hi talk2amulya,
i'm using simple QPushButton,i have one problem, in your code :



void YourButtonClass::mousePressEvent(QMouseEvent* event)
{

if (event->button() == Qt::LeftButton)
{
Timer->start(m_sec);
m_bMouseButtonDown = true;
}


how can i replace YourButtonClass with QPushButton?
is it possible?

spirit
14th February 2009, 09:24
install event filter for you button.


...
m_pb = new QPushButton(tr("Clear"), this);
m_pb->installEventFilter(this);
...
bool MyWidget::eventFilter(QObject *o, QEvent e)
{
if (o == m_pb && e->type() == QEvent::QEvent::MouseButtonPress) {
QMouseEvent *me = static_cast<QMouseEvent *>(e);
if (e->button() == Qt::LeftButton) {
Timer->start(m_sec);
m_bMouseButtonDown = true;
return true;
}
}
return QWidget::eventFilter(o, e);
}

aj2903
14th February 2009, 10:07
hi spirit

i have written the code in following manner :


abc.h
class abc:public QDialog,public QObject
{



protected :
bool eventFilter(QObject *o,QEvent *e):


}

I'm facing the following error:
abc.h:70: error: only constructors take base initializers

I don't know what the problem is ?
Kindly correct me where i'm going wrong

Thanks in Advanced

spirit
14th February 2009, 10:11
Qt doesnt support multiply inheritance from QObject, so you have to correct your code like this


class YourDialog: public QDialog
{
...
protected:
...
}

aj2903
14th February 2009, 10:15
after trying


class YourDialog: public QDialog
{
...
protected:
...
}

same error is occuring

spirit
14th February 2009, 10:17
show whole header file, plz.

aj2903
14th February 2009, 10:21
Here is the Header File



#ifndef ABC_H
#define ABC_H

#include <QDialog>
#include <QTimer>
#include <QMouseEvent>

class abc: public QDialog
{
Q_OBJECT

public:
abc(QWidget *parent = 0);
~abc;
public slots:
void log_data_refresh();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
bool eventFilter(QObject *obj,QEvent *event):

private slots:
...
void check_queue();
void closeEvent(QCloseEvent *event);
void showEvent(QShowEvent *event);

private:
QTimer *timer;
};

#endif

spirit
14th February 2009, 10:23
try to change ~abc; to ~abc();

aj2903
14th February 2009, 10:24
tried but same error.

spirit
14th February 2009, 10:28
try this change bool eventFilter(QObject *obj,QEvent *event): to bool eventFilter(QObject *obj,QEvent *event);

aj2903
14th February 2009, 10:30
this was the real problem thanks spirit.
:)

Lykurg
14th February 2009, 10:50
Wow,

first of all QWidget::setMouseTracking() is not needed. It is just for getting mouse move events which you aren't need. Then to use a QTimer is overkill because of all the signal and slots thing. Better use a simple QTime::currentTime (). Save the time stamp in press function and in the release function you just calculate the difference and if it is greater then 4 seconds emit a signal.


Lykurg

spirit
14th February 2009, 10:52
Wow,

first of all QWidget::setMouseTracking() is not needed. It is just for getting mouse move events which you aren't need. Then to use a QTimer is overkill because of all the signal and slots thing. Better use a simple QTime::currentTime (). Save the time stamp in press function and in the release function you just calculate the difference and if it is greater then 4 seconds emit a signal.


Lykurg
totally agree with you! :)

talk2amulya
14th February 2009, 10:58
so that means using QTimer is more expensive than using QTime::currentTime()?

Lykurg
14th February 2009, 11:40
Because I have too much time, or better to much work to get around, here is an example:


#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QtGui>

class myButton : public QPushButton
{
Q_OBJECT
public:
myButton(QWidget *parent = 0);
void setMinimumHoldTime(int msec)
{
m_minimumHoldTime = msec;
}
int minimumHoldTime() const
{
return m_minimumHoldTime;
}
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
signals:
void holdForMSec(int);
private:
QTime m_time;
int m_minimumHoldTime;
};

#endif // MYBUTTON_H



#include "mybutton.h"

myButton::myButton(QWidget *parent)
: QPushButton(parent), m_time(), m_minimumHoldTime(4000)
{}

void myButton::mousePressEvent(QMouseEvent *event)
{
m_time = QTime::currentTime();
QPushButton::mousePressEvent(event);
}

void myButton::mouseReleaseEvent(QMouseEvent *event)
{
int msec = m_time.elapsed();
// Do time check in the button class
if (m_minimumHoldTime < msec && rect().contains(event->pos()))
emit holdForMSec(msec);
// or let the reciver decide what to do
// if (rect().contains(event->pos()))
// emit holdForMSec(msec);
QPushButton::mouseReleaseEvent(event);
}


@talk2amulya: If you call QTimer::start(int) you start a new "event loop" (I don't know how QTimer is exactly implemented), to measure when the time is up and at which end a signal is emitted. And this continuous! Whereas QTime simple returns a time Object. Nothing more...

talk2amulya
14th February 2009, 11:51
hi lykurg,

first of all, thanks for investing your time on this..i have one doubt abt what u said..does QTimer really start its own event loop..cuz as far as i've seen, exec() is the only way to start your own event loop..but its always good to know alternative ways to solve a problem..r u sure it starts its own event loop?

Lykurg
14th February 2009, 12:14
Hi,

as I told I don't know exactly if QTimer starts its own thread or the main-gui-thread is used for (what is more likely), but QTimer::start() calls QObject::startTimer() which does nasty things in d->threadData->eventDispatcher.
Whereas QTime::currentTime() simply returns a QDate. So without deeper knowledge you can say QTime::currentTime() isn't so expensive. But to be true, the resource saving in that case isn't so much...

Lykurg

aj2903
14th February 2009, 12:15
thanks to Lykurg, spirit , talk2amulya for spending their valuable time and helping me to solve the problem.