PDA

View Full Version : How to ignore Button-Events in Qtopia?



Helmut Hönig
5th July 2007, 14:24
Hello folks,

I have a problem with events in Qtopia. If events occur, while our one-and-only main thread is doing some other stuff besides events handling, they are dispatched deferred. If events occur in the meantime, they might be delivered to buttons, which were not active, when the event actually happened. Therefor we wanted to be able to discard all pending button events, if desired.

The following simple example shows the problem: After pressing "start", that button should be disabled for 2 seconds and then, all intermediate button events should be discarded. While our eventFiltering-solution works on Windows, it fails on Qtopia. We tried different workarounds, but haven't yet found a solution for the problem. If you hit the disabled button in our example, the event is deferred until the button is enabled again and then dispatched. :(

It seems as if there is an event queue somewhere else, that is unreachable for us. Is there any idea, what went wrong? :confused:

Thanks for your help.
Helmut

==================

The example consists of:
MyWidget.cpp
MyWidget.h
PressDisabled.pro

==================
=== MyWidget.cpp ===
==================


/*
* The example shows a widget including a start button to start a longer job
* (a 2 seconds wait in the example). In our application, that job is done in
* the main thread without further event processing. The start button should
* therefore be visually deactivated in the meantime. After the job
* the start button gets enabled again to start another job.
*
* The problem is, that the user can hit the deactivated button during
* the job processing time. These hits should be ignored, when the button
* gets enabled again.
*
* On windows, we solved the problem with an event filter, which filters
* out the invalid presses after the job has completed.
*
* This mechanism seems not to work with Qtopia. We tried hard but were not
* able to filter out the invalid events, which lead to an automatic restart
* of the job. It seems as if the mouse events are stored somewhere outside
* the event queue and not reachable at the time when we want to discard them.
*
* Is there any idea for a workaround in Qtopia?
*/
#include <QApplication>
#include <QWidget>
#include <QTime>

#include "MyWidget.h"

MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
setFixedSize(75, 90);

count=new QLabel("0",this);
count->setGeometry(0, 0, 75, 30);

start = new QPushButton(tr("Start"), this);
start->setGeometry(0, 30, 75, 30);
connect(start, SIGNAL(clicked()), this, SLOT(startClicked()));

QPushButton *quit = new QPushButton(tr("Quit"), this);
quit->setGeometry(0, 60, 75, 30);
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
}

// a filter to be used for dicarding mouse events on the start button
bool MyWidget::eventFilter(QObject *obj, QEvent *event)
{
if ( obj==start &&
(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)) {
qDebug("BINGO: Button event filtered out.");
return true;
}
else {
return false;
}
}

// just a try to remove all events for the start button (but not working)
void MyWidget::dropButtonEvents() {
QCoreApplication::removePostedEvents(start);
}

// ==============================================
// the slot of the start button, that does the whole stuff
// ==============================================
void MyWidget::startClicked() {
qDebug("startClicked() entered");
count->setNum(count->text().toInt()+1);
// disable start button and show that on the screen
start->setEnabled(false);
QCoreApplication::processEvents(QEventLoop::Exclud eUserInputEvents);
start->installEventFilter(this);

qDebug("Processing started");
QTime time;
time.start();
// loop for a while to simulate some hard work ...
while(time.elapsed()<2000);
qDebug("Processing stopped");

// TODO: find a solution to clean up with Button Events
// the solution should also work with Qtopia!
dropButtonEvents();

// enable start button again
start->setEnabled(true);
// AllEvents used in processEvents, so we can filter buttons (at least on Windows)
QCoreApplication::processEvents(QEventLoop::AllEve nts);
start->removeEventFilter(this);

qDebug("startClicked() left");
}

int main(int argc, char *argv[])
{
// the basic application start with a single widget
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}

==================
=== MyWidget.h ===
==================


#include <QPushButton>
#include <QLabel>
#include <QEvent>

class MyWidget : public QWidget
{
Q_OBJECT

public:
MyWidget(QWidget *parent = 0);

QLabel *count;
QPushButton *start;

bool eventFilter(QObject *obj, QEvent *event);

void dropButtonEvents();

public slots:
void startClicked();

};

==================
=== PressDisabled.pro ===
==================

CONFIG += qt debug

SOURCES = MyWidget.cpp \

HEADERS = MyWidget.h \

FORMS =