Pritpal Bedi escreveu:
How an event which is not a SIGNAL can be retrieved for a widget.
See the code below: class to filter events and execute codeblocks.
----------------
file: events.cpp
----------------
#include <QObject>
#include <QEvent>
#include <QKeyEvent>
#include <QWidget>
#include <QString>
#include <QList>
#include "events.h"
#include "hbapi.h"
#include "hbvm.h"
#include "hbapiitm.h"
static Events *s = NULL;
Events::Events(QObject *parent) : QObject(parent)
{
}
Events::~Events()
{
}
bool Events::eventFilter(QObject *obj, QEvent *event)
{
QEvent::Type eventtype = event->type();
int found = -1;
bool ret;
for (int i = 0; i < list1.size(); ++i)
{
if( ( (QObject *) list1.at(i) == (QObject *) obj ) &&
( (QEvent::Type) list2.at(i) == (QEvent::Type) eventtype ) &&
( (bool) list4.at(i) == true ) )
{ found = i; break; }
}
if( found == -1 )
{
return false;
}
PHB_ITEM pObject;
PHB_ITEM pEvent;
pObject = hb_itemPutPtr( NULL, (QObject *) obj );
pEvent = hb_itemPutPtr( NULL, (QEvent *) event );
ret = hb_itemGetL( hb_vmEvalBlockV( (PHB_ITEM) list3.at(found), 2,
pObject, pEvent ) );
hb_itemRelease( pObject );
hb_itemRelease( pEvent );
switch (eventtype)
{
case QEvent::Close:
{
if( ret ) { event->accept(); } else { event->ignore(); }
return true;
break;
}
case QEvent::Enter:
{
return true;
break;
}
case QEvent::FocusIn:
{
return false;
break;
}
case QEvent::FocusOut:
{
return false;
break;
}
case QEvent::Hide:
{
return true;
break;
}
case QEvent::KeyPress:
{
return true;
break;
}
case QEvent::KeyRelease:
{
return true;
break;
}
case QEvent::Leave:
{
return true;
break;
}
case QEvent::Paint:
{
return false;
break;
}
case QEvent::Show:
{
return true;
break;
}
default:
break;
}
return true;
}
HB_FUNC( QT_QEVENTFILTER )
{
if( s == NULL )
{
s = new Events();
}
hb_retptr( (Events *) s );
}
HB_FUNC( QT_CONNECT_EVENT )
{
QObject * object = (QObject *) hb_parptr(1); // get object
int type = hb_parni(2); // get event type
PHB_ITEM codeblock = hb_itemNew( hb_param( 3, HB_IT_BLOCK |
HB_IT_BYREF ) ); // get codeblock
// create object s, if not created yet
if( s == NULL )
{
s = new Events();
}
// add event to event list
s->list1 << object;
s->list2 << (QEvent::Type) type;
s->list3 << codeblock;
s->list4 << true;
}
==============
file: events.h
==============
#ifndef EVENTS_H
#define EVENTS_H
#include <QObject>
#include <QEvent>
#include <QList>
#include "hbapi.h"
#include "hbapiitm.h"
class Events: public QObject
{
Q_OBJECT
public:
Events(QObject *parent = 0);
~Events();
QList<QObject*> list1;
QList<QEvent::Type> list2;
QList<PHB_ITEM> list3;
QList<bool> list4;
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
#endif
==========
How to use
==========
1. Get a pointer to event filter object (one for entire application)
pEventFilter := QT_QEVENTFILTER()
2. Install the event filter for each widget (only widgets where you need
to intercept events)
QT_QOBJECT_INSTALLEVENTFILTER( pWidget, pEventFilter )
3. Use the function QT_CONNECT_EVENT to connect a codeblock with the event:
QT_CONNECT_EVENT ( pWidget, QEvent_Close, bCodeBlock )
Some notes:
The class is functional, but is not complete.
File events.h require moc like the file slots.h.
The codeblock for event "close" require .t. or .f. as a result. .t.
close the window and .f. cancel the event.
Forgive my ausence in discussions. Personal/family questions require my
time/attention and i have only few hours each week to read/answer messages.
Regards,
Marcos Gambeta
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour