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

Reply via email to