QComboBox Signal FocusInEvent or Highlighted/Activated?
-
I am still getting a recursive function, except this time in a different part. I changed the return to:
@return QDialog::eventFilter(object, event);@ Once a user clicks on the comboBox and the event filter fires, it keeps looping as if the focusInEvent is being called. I am lost. -
[quote author="poporacer" date="1299217306"]I am still getting a recursive function, except this time in a different part. I changed the return to:
@return QDialog::eventFilter(object, event);@ Once a user clicks on the comboBox and the event filter fires, it keeps looping as if the focusInEvent is being called. I am lost.[/quote]You will end up in an endless loop if you work that way on focus in event. The reason is very simple:
Your combo box gets the focus, you put it to the QMessageBox. With closing the message box, it returns to the combo box, which results in calling the event filter... Hope you see the loop. And you also explicitly set the focus.
The base class event filter normally does nothing so returning false in the end should also work. True filters the event out, see "documentation":http://doc.qt.nokia.com/latest/qobject.html#eventFilter .
-
[quote author="Gerolf" date="1299230208"]The base class event filter normally does nothing so returning false in the end should also work. True filters the event out, see "documentation":http://doc.qt.nokia.com/latest/qobject.html#eventFilter .[/quote]
You never know if the base class' event filter does something, so it is good practice to call it. If it is "empty", it returns false anyways, if not it works as expected. Only leave the call to the base class' implementation out if you're absolutely sure what you are doing and you know for sure that you do not want the base class functionality. and even if the base's event filter is empty now, this might change in the future. So, call it and forget it :-)
This holds not only for eventFilter, but for the vast majority of virtual functions in Qt.
-
@Gerolf, Thanks for the link to the documentation. now I understand it better, you return true if you captured the event and do not want any further processing and false if you want to continue with normal event processing... Correct? But I don't see where I explicitly set the focus to the combobox. I do set the focus to another widget. I did this to try to prevent the recursiveness.
@Volker, You say that it is good practice to call the base class' event filter. I am not sure what you mean by this. Are you saying that in pest practices, it should be included in the end as I have it or instead of returning false you should always
@return QDialog::eventFilter(object, event);@
??
And after seeing how often the focusInEvent is triggered, I think I will change it to mouseClick
Thanks![EDIT: fixed @-tags, Volker]
-
[quote author="poporacer" date="1299385172"@Volker, You say that it is good practice to call the base class' event filter. I am not sure what you mean by this. Are you saying that in pest practices, it should be included in the end as I have it or instead of returning false you should always
@return QDialog::eventFilter(object, event);@
??
And after seeing how often the focusInEvent is triggered, I think I will change it to mouseClick
Thanks!
[/quote]For all the cases where you do not handle the event yourself, call the base class' implementation and return its value. For the cases where you handle the event yourself, you must decide if the base class should get the event too; most times the answer is "yes", but there is no general guideline here.
Be aware that this holds for almost every virtual method that you reimplement, not only eventFilter.
-
Well, I still had the recursive errors and the combobox wouldn't show. I could not figure it out. I finally tried something out of the blue and it worked. I am not sure why but this is what worked for those searching.
My widget was subclassed from a QDialog so I thought the proper method to return was @return QDialog::eventFilter(object, event); @
But that didn't work. Here is what I have to make it work:
In .h file
@bool eventFilter (QObject*, QEvent*);@In constructor
@MainPage::MainPage(QWidget *parent) :
QDialog(parent), //note: the base class is QDialog...correct?
ui(new Ui::MainPage)
{
ui->cmbName->installEventFilter(this);
ui->cmbStreet->installEventFilter(this)@
}
Method:@bool MainPage::eventFilter (QObject *object, QEvent *event)
{int row =addressModel->rowCount(); if (!row ==0) { if (object== ui->cmbName) { if (event->type()==QEvent::MouseButtonPress) { int test=QMessageBox::warning(this,"Table loaded", "If you select a new Name, \n " "a new table will be loaded. \n" "Do you want to load a new table?", QMessageBox::Yes | QMessageBox::No ); if (test==QMessageBox::No) { ui->txtName->setFocus(); return true; } else { ui->txtName->setText(""); setLapTable("FName = ''"); //this resets the table view to a blank table return QObject::event( event); // note: Return QObject! This change made it work } } } else if(object==ui->cmbStreet) { if (event->type()==QEvent::MouseButtonPress) { int test=QMessageBox::warning(this,"Table loaded", "If you select a new street, \n " "a new table will be loaded. \n" "Do you want to load a new table?", QMessageBox::Yes | QMessageBox::No ); if (test==QMessageBox::No) { ui->txtLineDescription->setFocus(); return true; } else { ui->txtName->setText(""); setLapTable("FName = ''"); //this resets the table view to a blank table return QObject::event( event); // note..Return QObject! This change made it work } } return QObject::event( event); } return QObject::event( event);
}
return QObject::event( event); //I thought you would return to the base class.QDialog?
}@
This works as it should!
Thanks for your help! -
Returning QObject::event() is definiteley wrong! Don't do this! You might end up in an endlessloop too!
Return QDialog::eventFilter(). If that is going to create an endless loop, you should evaluate why!
Also, I suspect the QMessageBox to mess up things. A whole bunch of events is generated during its execution and until the flow of control returns to the event filter.
Some other remarks:
First:
@
if (!row ==0)
// you know of
if(row != 0)
@Second:
Check at first for the event type. You do net need the row if you are not dealing with a mouse press event:@
bool MainPage::eventFilter (QObject *object, QEvent *event) {
if(event->type() != QEvent::MouseButtonPress)
return QDialog::eventFilter(object, event);int row = addressModel->rowCount();
if(row == 0)
return QDialog::eventFilter(object, event);if(object == ui->cmbName) {
// do your work here
} else if(object == ui->cmbStreet) {
// do your work here
}// just in case we fall through
return QDialog::eventFilter(object, event);
}
@