Qt 段错误试图在测试应用程序中显示 2 个对话框

Qt segfault trying to show 2 dialogs in test application

我正在学习 Qt。我在一个简单的测试应用程序中重现了我的问题。我创建了一个新项目。添加了 2 个对话框 Dialog1 和 Dialog2。我添加了 2 个菜单项来调用 dialog1 和 dialog2。

window 的主要头文件如下所示:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "dialog1.h"
#include "dialog2.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_actiondialog1_triggered();

    void on_actiondialog2_triggered();

private:
    Ui::MainWindow *ui;
    Dialog1 *mDialog1;
    Dialog2 *mDialog2;
};
#endif // MAINWINDOW_H

主要 window 的 cpp 如下所示:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
      , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_actiondialog1_triggered()
{
     if (!mDialog1) {
        mDialog1 = new Dialog1(this);
        mDialog1->setModal(false);
     }
     mDialog1->show();
     mDialog1->activateWindow();
 }

 void MainWindow::on_actiondialog2_triggered()
 {

    if (!mDialog2) {
        mDialog2 = new Dialog2(this);
        mDialog2->setModal(false);
    }
    mDialog2->show();
    mDialog2->activateWindow();
 }

所以它基本上是空的……如果我只通过注释掉相关部分来显示一个对话框,它就可以工作,但是一旦我想使用 2 个或更多,就会出现段错误。给定的对话框构造函数甚至不再被调用。

我正在使用:

Qt Creator 4.12.3
Based on Qt 5.14.2 (GCC 5.3.1 20160406 (Red Hat 5.3.1-6), 64 bit)
Built on Jun 16 2020 04:15:35

我不明白我做错了什么。有人可以澄清一下吗?

首先,它与 Qt 无关。这是关于你的 implementation:In 你的构造函数,我没有看到初始化 mDialog1 和 mDialog2 的代码。 那么,当转到插槽时, mDialog1 的值是多少?它是未定义的,尤其是在发布版本中。 这是其中一种方法: 在您的构造函数中,只需创建对象:

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mDialog1 = new Dialog1(this);
    mDialog2 = new Dialog2(this);
}

然后在插槽中(不需要检查指针):

void MainWindow::on_actiondialog1_triggered()
{
     mDialog1->setModal(false); //Not required, because of show()
     mDialog1->show();
     mDialog1->activateWindow();
 }

另一种方法,按需创建对象:

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
//Initalize these members
m_dialog1 = nullptr;
m_dialog2 = nullptr;

}

然后:

 void MainWindow::on_actiondialog2_triggered()
 {

if (!mDialog2) 
{
    mDialog2 = new Dialog2(this);
    mDialog2->setModal(false);
}
mDialog2->show();
mDialog2->activateWindow();

}