异常的奇怪行为(某些未调用的方法被执行)

时间:2012-09-25 02:29:41

标签: c++ qt exception

我一直在努力应对一种我自己无法解决的奇怪行为,所以我在这里。

我正在为一个运行良好的控制台应用程序创建一个GUI。用户可以选择要加载的文件,也可以重新加载以前选择的文件。这两个动作由两个不同的slots处理。我正在使用exceptions处理文件格式的错误,并且它在控制台版本中运行良好,但目前GUI还不太好......

当openFile slot中出现错误时,catch块使其工作并且方法按预期停止但是另一个插槽被意外调用。我不知道为什么,所以不知道如何纠正这种行为。

以下是相关代码:

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;
    }
}

使用环境:

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);

注意:经过大量调试后,我发现在执行catch块后调用该类的moc文件中的一个函数:

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);
}

使用_id = 1调用它,它解释了另一个插槽的意外执行。但为什么会这样呢?有没有人可以解释如何避免这种情况?我已经创建了自己的应用程序类派生自qApplication并覆盖notify(),但这不会改变任何内容。

1 个答案:

答案 0 :(得分:2)

应:

reloadAction = new QAction(QIcon(":images/reload.png"), tr("&Reload"), this);
connect(openAction, SIGNAL(triggered()), myLoader, SLOT(reloadSourceFile()));
menuTop->addAction(reloadAction);

是:

reloadAction = new QAction(QIcon(":images/reload.png"), tr("&Reload"), this);
connect(reloadAction, SIGNAL(triggered()), myLoader, SLOT(reloadSourceFile()));
//      ^^^^^^^^^^^^
menuTop->addAction(reloadAction);