启动时关闭QMainWindow?

16

我有一个使用QMainWindow派生类作为主UI的Qt应用程序。在启动时,我想进行一些安全检查,如果失败,则向用户显示一条消息并关闭主窗口。目前我在QMainWindow构造函数中进行这些检查,但如果调用close方法,则什么也不会发生,应用程序将继续运行。例如:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    setupUi(this);
    ...
    if (checkFails())
    {
        QMessageBox::warning(this, tr("Error"), tr("You cannot run this app"));
        // This has no effect
        close();
    }
}

或者我可以在主函数中进行检查,但这样就失去了显示特定语言消息框的能力(根据情况看起来tr宏只能在QObject派生类内工作)。

有什么想法可以在启动时关闭主窗口或使tr宏在QObject派生类之外工作吗?

4个回答

30

在您成功关闭主窗口之前,事件循环需要处于运行状态。由于您可能首先构造一个窗口,然后再启动事件循环,因此close()调用没有效果。请尝试以下解决方案:

QTimer::singleShot(0, this, SLOT(close()));

QTimer::singleShot()函数会在事件循环开始后立即触发,然后调用应用程序主窗口的close()方法。

上述解决方案可能会导致主应用程序窗口短暂可见,从而引起不必要的闪烁。

更清晰的解决方案应该在构建主窗口之前执行安全检查。由于tr()也是QObject上的静态方法,因此可以从主函数中完成这一步骤。


1
QMetaObject::invokeMethod( this, "close", Qt::QueuedConnection ); 可以实现相同的功能,但我认为意图更加清晰。 - Marcus10110
1
@Marcus10110,好建议,我同意这样做更好。 - Ton van den Heuvel

3
大多数应用程序启动有三个步骤:1)构建窗口;2)显示窗口;3)启动事件循环。您可以通过向窗口类添加一个标志(其值由窗口构造函数设置),使步骤2和3取决于步骤1的成功与否。
窗口类:
class myMainWindowClass : public QMainWindow
{
    Q_OBJECT
public:
    myMainWindowClass()
    : isFinished_(false) { if (error) isFinished_ = true; } // constructor

    bool isFinished() const { return isFinished_; }
private:
    bool isFinished_;
} 

应用程序代码:

int main()
{
    myMainWindowClass main_window(); // Step 1

    // Finish early if isFinished flag is set
    if (main_window.isFinished())
      return 0;

    main_window.show(); // Step 2
    return a.exec(); // Step 3
}

这也应该避免任何闪烁,因为应用程序将在窗口 show() 前结束。


2
`tr` 是 QObject 的一个 公共静态成员。您应该能够在主函数中调用 `QObject::tr("Error")`。

0
你尝试过先使用hide()隐藏窗口(当调用close()时应该会自动发生),看看这是否允许close()销毁窗口。
如果这不起作用,你可以尝试destroy(true, true)销毁窗口以及任何子窗口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接