PDA

View Full Version : Installing Event Filters



Dumbledore
12th October 2007, 20:30
Good evening,

I have code as follows:



MChat::MChat(QMainWindow *parent) : QMainWindow(parent) {
setupUi(this);
inputChat->installEventFilter(this);
connect(reinterpret_cast<QObject*>(this), SIGNAL(pressedReturn()),
reinterpret_cast<QObject*>(sendButton), SLOT(animateClick()));
}

bool MChat::eventFilter(QObject *obj, QEvent *event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = reinterpret_cast<QKeyEvent *>(event);
if ( keyEvent->key() == Qt::Key_Return ) {
emit pressedReturn();
return true;
}
else {
// continue standard event processing
return QObject::eventFilter(obj, event);
}
}
}


I personally don't think this is good. I'd like to have the eventFilter as a method of inputChat. But to do this I'd have to directly edit the code generated by uic. At least, that's the only way I know. Perhaps someone could show me a better way?

wysota
12th October 2007, 20:34
You can always subclass the widget and implement the functionality there.

Dumbledore
12th October 2007, 22:22
If inputChat is an object of QTextEdit, how can I add signals to it (cause that's essentially what I'm doing). The way I see it, inputChat would have to be changed into a new specialized version of QTextEdit which is kind of hard to do unless I change the code uic generates directly.

I'm sure there is a better way I just don't know how to do it.

jacek
12th October 2007, 22:51
reinterpret_cast<QObject*>(this), reinterpret_cast<QObject*>(sendButton),
You don't need any casts here as both sendButton and "this" are QObjects.

Also if you use reinterpret cast anywhere, you should have very good reasons to do so, because it might break portability.


But to do this I'd have to directly edit the code generated by uic.
You don't have to: http://doc.trolltech.com/4.3/designer-using-custom-widgets.html#promoting-widgets
Another solution is to write a widget plugin, but it's a bit of work, so you usually don't do that for custom widgets that are used only in one place.

wysota
12th October 2007, 22:52
You can subclass QTextEdit and implement the added functionality. In Designer you can then promote your QTextEdit widget to your subclass, hence avoiding the need to alter uic generated code.

Dumbledore
12th October 2007, 23:32
I have been playing around with the promote feature of designer. I discovered it on my own and realized it must be pertinent. However, it is no simple task to specialize a widget if you are new to this. The compiler whines incessantly when I promote the TextEdit widget to TextEditEx specifying header file AllTextEx.h.

When I do this:

"AllTextEx.h"



class QTextEditEx : public QTextEdit {
Q_OBJECT

protected:
bool eventFilter(QObject* obj, QEvent *event);
signals:
void pressedReturn();
};


I get: ./AllTextEx.h:2: error: expected class-name before '{' token...

When I do this:



#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QMainWindow>
#include <QtGui/QMenu>
#include <QtGui/QMenuBar>
#include <QtGui/QPushButton>
#include <QtGui/QStatusBar>
#include <QtGui/QTextBrowser>
#include <QtGui/QWidget>

class QTextEditEx : public QTextEdit {
Q_OBJECT

protected:
bool eventFilter(QObject* obj, QEvent *event);
signals:
void pressedReturn();
};


I get:

ui_MChat.h: In member function `void Ui_MChat::setupUi(QMainWindow*)':
ui_MChat.h:47: error: no matching function for call to `QTextEditEx::QTextEditEx(QWidget*&)'

And even something like this yields linker errors:


#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QMainWindow>
#include <QtGui/QMenu>
#include <QtGui/QMenuBar>
#include <QtGui/QPushButton>
#include <QtGui/QStatusBar>
#include <QtGui/QTextBrowser>
#include <QtGui/QWidget>

class QTextEditEx : public QTextEdit {
Q_OBJECT
private:
QWidget* mainWindow;
public:
QTextEditEx(QWidget* widget) : mainWindow(widget) {}
protected:
bool eventFilter(QObject* obj, QEvent *event);
signals:
void pressedReturn();
};


I get:
MChat.cpp:(.text$_ZN8Ui_MChat7setupUiEP11QMainWind ow[Ui_MChat::setupUi(QMainWindow*)]+0x343): undefined reference to `vtable for QTextEditEx'
MChat.cpp:(.text$_ZN8Ui_MChat7setupUiEP11QMainWind ow[Ui_MChat::setupUi(QMainWindow*)]+0x353): undefined reference to `vtable for QTextEditEx'

wysota
12th October 2007, 23:37
What linker errors? QTextEditEx constructor should call QTextEdit constructor. And you don't need an event filter in that case. Simply override the event handler you wish to change.

jacek
12th October 2007, 23:40
I get: ./AllTextEx.h:2: error: expected class-name before '{' token...
Because of missing #include <QTextEdit>.


I get:
MChat.cpp.text$_ZN8Ui_MChat7setupUiEP11QMainWind ow[Ui_MChat::setupUi(QMainWindow*)]+0x343): undefined reference to `vtable for QTextEditEx'
MChat.cpp.text$_ZN8Ui_MChat7setupUiEP11QMainWind ow[Ui_MChat::setupUi(QMainWindow*)]+0x353): undefined reference to `vtable for QTextEditEx'
Make sure that the QTextEditEx code is included in your .pro file.

Dumbledore
12th October 2007, 23:52
OK, I have included it in my .pro file and I've specified it in Designer and set it to global, and I'm including <QTextEdit>


"QTextEditEx constructor should call QTextEdit constructor"
You would think so, but I'm getting this error still:

ui_MChat.h: In member function `void Ui_MChat::setupUi(QMainWindow*)':
ui_MChat.h:47: error: no matching function for call to `QTextEditEx::QTextEditEx(QWidge
./AllTextEx.h:3: note: candidates are: QTextEditEx::QTextEditEx()
./AllTextEx.h:3: note: QTextEditEx::QTextEditEx(const QTextEditEx&)

jacek
13th October 2007, 00:02
You would think so, but I'm getting this error still:

ui_MChat.h: In member function `void Ui_MChat::setupUi(QMainWindow*)':
ui_MChat.h:47: error: no matching function for call to `QTextEditEx::QTextEditEx(QWidge
./AllTextEx.h:3: note: candidates are: QTextEditEx::QTextEditEx()
./AllTextEx.h:3: note: QTextEditEx::QTextEditEx(const QTextEditEx&)
Add:

public:
QTextEditEx( QWidget *parent = 0 ) : QTextEdit( parent) {}
to QRextEditEx definition.

Dumbledore
13th October 2007, 00:09
Yes that works. But is this normal to have to do? (I got a bad vibe through me as I added that code)

In any case: thanks for your help guys.

Dumbledore
13th October 2007, 00:58
#include <QTextEdit>

class QTextEditEx : public QTextEdit {
Q_OBJECT
public:
QTextEditEx(QWidget* parent = 0) : QTextEdit(parent) {}
protected:
bool event(QEvent*);
signals:
void pressedReturn();
};

jacek
13th October 2007, 01:27
But is this normal to have to do? (I got a bad vibe through me as I added that code)
Yes, constructors aren't inherited.