I’ve been struggling with a really strange behavior that I do not manage to resolve on my own, so here I am.
I’m creating an GUI for a console application which works great. The user can either select a file to be loaded or reload a previous selected file. Those two actions are handled with two different slots. I’m handling errors in the file’s format with exceptions and it worked great in the console version, but for the GUI not too well for the moment…
When an error is thrown in the openFile slot, the catch block makes his work and the method is stopped as expected BUT then the other slot is being called unexpectedly. I have no idea why and so have no idea how to correct that behavior.
Here’s the relevant code :
void Loader::openSourceFile()
{
fileName = QFileDialog::getOpenFileName(myWindow, tr("Select source file"), QString(), tr("Text files (*.txt)"));
try{
parseSourceFile();
} catch(MyException &e)
{
QString msg = QString(e.what());
myWindow->alertUser(msg);
return;
}
}
void Loader::reloadSourceFile()
{
try{
parseSourceFile();
} catch(MyException &e)
{
QString msg = QString(e.what());
myWindow->alertUser(msg);
return;
}
}
the context of use :
myLoader = new Loader(this);
menuTop = menuBar()->addMenu(tr("&File"));
//open source file
openAction = new QAction(QIcon(":images/document.png"), tr("&Open"), this);
connect(openAction, SIGNAL(triggered()), myLoader, SLOT(openSourceFile()));
menuTop->addAction(openAction);
//reload source file
reloadAction = new QAction(QIcon(":images/reload.png"), tr("&Reload"), this);
connect(openAction, SIGNAL(triggered()), myLoader, SLOT(reloadSourceFile()));
menuTop->addAction(reloadAction);
Note : after heavy debugging, I found that one function in the moc file of that class is being called after the execution of the catch block :
void Loader::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
Loader *_t = static_cast<Loader *>(_o);
switch (_id) {
case 0: _t->openSourceFile(); break;
case 1: _t->reloadSourceFile(); break;
default: ;
}
}
Q_UNUSED(_a);
}
it is called with _id = 1 which explain the undesired execution of the other slot. But why this happens ??? Does anybody could explain how this can be avoided ? I’ve already made my own application class derived from qApplication and override notify() but that does not change anything.
Should:
be: