PDA

View Full Version : event(QEvent * event)



rajaraob
21st February 2007, 14:55
hi
i am facing some problem to capture key events in subclass of QObject. i am using qt 3.3.5 . i wanted to implement key board navigation on QTabWidget objects contained in QObect

Following is my code


bool event(QEvent*); is declared in ABC.h


bool ABC::event(QEvent * event)
{

int cnt = m_pMasterTab->count();// m_pMasterTab is QTabWidget declared at private member of ABC class

if(event->type() == QEvent::KeyPress)
{
QKeyEvent *k = (QKeyEvent*)event;
Qt::Key keyPressed = (Qt::Key)k->key();
if(keyPressed == Qt::Key_Left)
{
int indx = m_pMasterTab->currentPageIndex();
m_pMasterTab->setCurrentPage ((indx ==0)?cnt:indx-1 ) ;
}
if(keyPressed == Qt::Key_Right)
{
int indx = m_pMasterTab->currentPageIndex();
m_pMasterTab->setCurrentPage ((indx+1)%cnt ) ;
}
return true;
}
else
return QObject::event(event);
}


Please do let me know your insigths . Thanks in advance.

regards
raja rao

camel
22nd February 2007, 10:51
hi
i am facing some problem to capture key events in subclass of QObject.
What kind of problems?


Please do let me know your insigths
The only "insight" I can give you at this point(i.e. without knowing what your problem is) is, that you swallow all keypress events. If that is not what you want you should probably rather do



bool ABC::event(QEvent * event)
{

int cnt = m_pMasterTab->count();// m_pMasterTab is QTabWidget declared at private member of ABC class

if(event->type() == QEvent::KeyPress) {
QKeyEvent *k = (QKeyEvent*)event;
Qt::Key keyPressed = (Qt::Key)k->key();
if (keyPressed == Qt::Key_Left) {
int indx = m_pMasterTab->currentPageIndex();
m_pMasterTab->setCurrentPage ((indx ==0)?cnt:indx-1 ) ;
return true;

} else if (keyPressed == Qt::Key_Right) {
int indx = m_pMasterTab->currentPageIndex();
m_pMasterTab->setCurrentPage ((indx+1)%cnt );
return true;
}
}
//is ABC a direct child of QObject?
//Wouldn't it be better to call the event function of the parent class here?
return QObject::event(event);
}


Would it perhaps be easier to use an Event Filter (http://doc.trolltech.com/3.3/qobject.html#installEventFilter)?

rajaraob
22nd February 2007, 11:08
thanks for you reply .

In my above code ,
all keyboard events have been recognised on QTAbWidget except left and right arrows.

is it a bug or any reason in 3.3.5 versions?

thanks
raja rao

camel
22nd February 2007, 11:17
In my above code ,
all keyboard events have been recognised on QTAbWidget except left and right arrows.

I am sorry, I am not sure I understand. The QTabWidget receives all keyboard event except left and right arrows?


Could you please create a small (but complete) programm that shows this behaviour? Any solution would have to include more information than you gave here. What type is ABC? How is ABC used etc.


is it a bug or any reason in 3.3.5 versions?
The chances are much better that there is a bug in your code, or that how you think event propagation works, is not how it really does work...

rajaraob
22nd February 2007, 11:28
Here is my modified code with eventfilter and installedeventfilters(...)

class ABC : public QObject
{
private :
QTabWidget *m_pMasterTab ;
Q_OBJECT

public :
ABC();
};

void ABC::ABC()
{
m_pMasterTab = new QTabWidget("mytabwidget");
m_pMasterTab->installEventFilter(this);//event filter
}
//Event filter
bool ABC::eventFilter(QObject * object, QEvent * event)
{
int cnt = m_pMasterTab->count();

if(event->type() == QEvent::KeyPress)
{
QKeyEvent *k = (QKeyEvent*)event;
Qt::Key keyPressed = (Qt::Key)k->key();
if(keyPressed == Qt::Key_Left)
{
int indx = m_pMasterTab->currentPageIndex();
m_pMasterTab->setCurrentPage ((indx ==0)?cnt:indx-1 ) ;
}
if(keyPressed == Qt::Key_Right)
{
int indx = m_pMasterTab->currentPageIndex();
m_pMasterTab->setCurrentPage ((indx+1)%cnt ) ;
}

return true;
}
else
return QObject::eventFilter(object,event);
}


This is my complete code of implementation .
If i print key value , i can see every key is recognised except left and right arrows.

regards
raja rao

camel
22nd February 2007, 11:49
A complete example, is for example this:

The main.cpp


#include "qapplication.h"
#include "qlabel.h"
#include "qtabwidget.h"

class ABC : public QTabWidget
{
Q_OBJECT
public:
ABC(QWidget * parent = 0, const char * name = 0, WFlags f = 0)
: QTabWidget(parent, name, f) { }

protected:
bool event(QEvent* e)
{
if(e->type() == QEvent::KeyPress) {
QKeyEvent *k = (QKeyEvent*)e;
Qt::Key keyPressed = (Qt::Key)k->key();
if (keyPressed == Qt::Key_Left) {
int indx = currentPageIndex();
setCurrentPage ((indx ==0)?count():indx-1 ) ;
return true;

} else if (keyPressed == Qt::Key_Right) {
int indx = currentPageIndex();
setCurrentPage ((indx+1)%count() );
return true;
}
}
return QTabWidget::event(e);
}
};

int main(int argc, char* argv[])
{
QApplication app(argc, argv);

ABC *abc = new ABC();

QLabel *label1 = new QLabel("Label1", abc);
abc->addTab(label1, "Label1");

QLabel *label2 = new QLabel("Label2", abc);
abc->addTab(label2, "Label2");

abc->show();

return app.exec();
}
#include "main.moc"


And then:

qmake -project
qmake
make

Sometimes it is better to inherrit than to wrap....

Now, the problem is that you do want to change the behaviour of the tabwidget, but you do not recognize the key event?

camel
22nd February 2007, 12:05
And here you got a version that uses eventfilters:

#include "qapplication.h"
#include "qlabel.h"
#include "qtabwidget.h"

class MyEventFilter : public QObject
{
Q_OBJECT
public:
MyEventFilter(QWidget *parent = 0, const char *name = 0)
: QObject(parent, name) { }

bool eventFilter(QObject *watched, QEvent *e)
{
if (watched->inherits("QTabWidget")) {
QTabWidget *tab = (QTabWidget*)watched;
if(e->type() == QEvent::KeyPress) {
QKeyEvent *k = (QKeyEvent*)e;
Qt::Key keyPressed = (Qt::Key)k->key();
if (keyPressed == Qt::Key_Left) {
int indx = tab->currentPageIndex();
tab->setCurrentPage ((indx ==0)?tab->count():indx-1 ) ;
return true;

} else if (keyPressed == Qt::Key_Right) {
int indx = tab->currentPageIndex();
tab->setCurrentPage ((indx+1)%tab->count() );
return true;
}
}
}
return false;
}
};

int main(int argc, char* argv[])
{
QApplication app(argc, argv);

QTabWidget *tab = new QTabWidget;

QLabel *label1 = new QLabel("Label1", tab);
tab->addTab(label1, "Label1");

QLabel *label2 = new QLabel("Label2", tab);
tab->addTab(label2, "Label2");

tab->installEventFilter(new MyEventFilter(tab));

tab->show();

return app.exec();
}
#include "main.moc"

camel
22nd February 2007, 14:10
Now that we have something which we can actually work with(and guess what the problem is) we can try out what is wrong.

What is wrong, is that the QTabWidget does not even get the left and right key-presses, since those are actually taken up by a child widget of its, QTabBar. To change the behaviour of the tabbar, we have to install an eventfilter onto it. And voila it works (As I would imaging you intendet...)


#include "qapplication.h"
#include "qlabel.h"
#include "qtabwidget.h"
#include "qtabbar.h"
#include "qtextedit.h"

class ABC : public QTabWidget
{
Q_OBJECT
public:
ABC(QWidget * parent = 0, const char * name = 0, WFlags f = 0)
: QTabWidget(parent, name, f)
{
tabBar()->installEventFilter(this);
}

virtual bool eventFilter(QObject *watched, QEvent *e)
{
if (watched == tabBar()) {

if(e->type() == QEvent::KeyPress) {
QKeyEvent *k = (QKeyEvent*)e;
Qt::Key keyPressed = (Qt::Key)k->key();

if (keyPressed == Qt::Key_Left) {
int indx = currentPageIndex();
setCurrentPage ((indx==0)?count()-1:indx-1 ) ;
return true;

} else if (keyPressed == Qt::Key_Right) {
int indx = currentPageIndex();
setCurrentPage ((indx+1)%count() );
return true;
}
}
}
return QTabWidget::eventFilter(watched, e);
}

protected:
};

int main(int argc, char* argv[])
{
QApplication app(argc, argv);

ABC *abc = new ABC();

QLabel *label1 = new QLabel("Label1", abc);
abc->addTab(label1, "Label1");

QLabel *label2 = new QLabel("Label2", abc);
abc->addTab(label2, "Label2");

QTextEdit *edit1 = new QTextEdit(abc);
abc->addTab(edit1, "Edit1");

abc->show();

return app.exec();
}

#include "main.moc"

rajaraob
26th February 2007, 12:20
Hi,
why is my eventFilters() on QTabWidget (..) is not able filter events of left and right arrows key board . where as same code is recognising up and down arrows
regards
raja rao

camel
26th February 2007, 21:25
Hi,
why is my eventFilters() on QTabWidget (..) is not able filter events of left and right arrows key board . where as same code is recognising up and down arrows


Because those events (left and right) are taken by the child widget. (The Tabbar) Since the tabbar does not care for the other key events, they are propagated to the qtabwidget.

This is why I had to install a event filter to override this behaviour (which you can only do through sub-classing, because this is the only way you can gain access to it.).