PDA

View Full Version : no MouseButtonRelease event for QComboBox



Beluvius
30th March 2006, 15:53
Hi all,

I am trying to catch all mouse button events to make a record/play functionality in my GUI, and it is working quite ok now.

However, I find that any QComboBox does have the MouseButtonPress event when it is clicked, but never has a MouseButtonRelease event. Not even when an item of the comboBox is selected. Is there a reason for this, or am I missing something?

Ps. I am installing an event filter for all QObjects with installEventFilter.

Greetings to all
Beluvius

jpn
30th March 2006, 16:27
Edit: install the same event filter on combo box's childrens to see who receive the events.

I ran some little tests.. ;)



comboBox->installEventFilter(this);
foreach (QObject* child, comboBox->view()->children())
child->installEventFilter(this);
foreach (QObject* child, comboBox->children())
child->installEventFilter(this);




bool ComboTester::eventFilter(QObject* o, QEvent* e) {
if (e->type() == QEvent::MouseButtonPress) {
qDebug() << "QEvent::MouseButtonPress:";
o->dumpObjectInfo();
} else if (e->type() == QEvent::MouseButtonRelease) {
qDebug() << "QEvent::MouseButtonRelease:";
o->dumpObjectInfo();
} if (e->type() == QEvent::KeyPress) {
qDebug() << "QEvent::KeyPress:";
o->dumpObjectInfo();
} else if (e->type() == QEvent::KeyRelease) {
qDebug() << "QEvent::KeyRelease:";
o->dumpObjectInfo();
}
return false;
}


Results:

When clicking a mouse button on a combo box, the output is:


QEvent::MouseButtonPress:
OBJECT QComboBox::comboBox
QEvent::MouseButtonRelease:
OBJECT QComboBoxPrivateContainer::unnamed


When clicking a mouse button on a combo box's view (popup), the output is:


QEvent::MouseButtonPress:
OBJECT QAbstractScrollAreaViewport::qt_scrollarea_viewpor t
QEvent::MouseButtonRelease:
OBJECT QAbstractScrollAreaViewport::qt_scrollarea_viewpor t


When pressing a key which does not open the combo, the output is:


QEvent::KeyPress:
OBJECT QComboBox::comboBox
QEvent::KeyRelease:
OBJECT QComboBox::comboBox


When pressing a key which opens the combo, the output is:


QEvent::KeyPress:
OBJECT QComboBox::comboBox
QEvent::KeyRelease:
OBJECT QComboBoxPrivateContainer::unnamed

Beluvius
31st March 2006, 08:19
Hi,

I did a similar thing, but forgot the comboBox->view() children. On my way home I thought about something similar, and now you answered my suspicions.

Edit: ok, I have tested by adding the view()->children() as well and now I do receive the mouseButtonReleases. However, for some reason, the comboBox does not 'work' anymore. If I click in a listitem in the comboBox, the item is not selected anymore and the comboBox does not 'collapse'. Did you have the same problem?

Thanks!
Beluvius

Beluvius
31st March 2006, 10:13
After running some more tests, I get different results. I never get the:
QEvent::MouseButtonRelease:
OBJECT QComboBoxPrivateContainer::unnamed

When I click a combobox, and release the button (without moving), I get:
QEvent::MouseButtonPress:
OBJECT QComboBox::testbox
and the list expands
Clicking on the same spot (without moving the mouse), I get:
QEvent::MouseButtonRelease:
OBJECT QComboBox::testbox
and the list collapses (no change to selection)

My code:
test.h:


#include <QtGui/QtGui>

class Test: public QObject
{
Q_OBJECT
public:
bool eventFilter(QObject *o, QEvent *e);
};


test.cpp


#include "test.h"
bool Test::eventFilter(QObject *o, QEvent *e)
{
if (e->type() == QEvent::MouseButtonPress) {
qDebug() << "QEvent::MouseButtonPress:";
o->dumpObjectInfo();
} else if (e->type() == QEvent::MouseButtonRelease) {
qDebug() << "QEvent::MouseButtonRelease:";
o->dumpObjectInfo();
} if (e->type() == QEvent::KeyPress) {
qDebug() << "QEvent::KeyPress:";
o->dumpObjectInfo();
} else if (e->type() == QEvent::KeyRelease) {
qDebug() << "QEvent::KeyRelease:";
o->dumpObjectInfo();
}
return false;
}

void addit(QObject * o, Test * t)
{
o->installEventFilter(t);
foreach (QObject * cobj, o->children())
cobj->installEventFilter(t);
}


int main(int argc, char * argv[])
{
QApplication app(argc, argv);
QComboBox * box = new QComboBox();
Test * test = new Test();
addit(box, test);
foreach (QObject * cobj, box->view()->children())
addit(cobj, test);
box->setObjectName("testbox");
box->addItem("foo 1");
box->addItem("foo 2");
box->addItem("foo 3");
box->show();
return app.exec();
}


to compile:
moc test.h -o test_moc.cpp
g++ test.cpp test_moc.cpp -I /usr/local/Trolltech/Qt4.1.0/include -L /usr/local/Trolltech/Qt4.1.0/lib -lQtGui_debug -lQtCore_debug

I don't understand why the QComboBoxPrivateContainer::unnamed is not shown here.

Greetings,
Beluvius

jpn
31st March 2006, 10:36
It is a bit complicated, but let me try to explain..

It seems that the QComboBoxPrivateContainer (which is combo boxes child, not the view's child) does not get instantiated right away. Actually it doesn't get instantiated until certain QComboBox's methods (for example view()/setView(), setEditable(), shopPopu()..) are called.

Try this:


addit(box, test);
box->view(); // or any other dummy call to force the private container to get instantiated
foreach (QObject * cobj, box->children())
addit(cobj, test);


Cheers! ;)

Beluvius
31st March 2006, 12:58
Ok, I have got it working now for the small example. It makes sense that the view is created later than the comboBox, but also slightly inconvenient.

Now another problem arose when recording the events. For some reason the new selection in the combobox is not shown when recording, but it is when replaying... But that is simply an error in my code.

Ps. Nice town you are living in, been there once. Knew some people there, but they moved.

Thanks,
Beluvius