【问题标题】:Qt segfault trying to show 2 dialogs in test applicationQt segfault 试图在测试应用程序中显示 2 个对话框
【发布时间】:2020-06-29 07:26:29
【问题描述】:

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

主窗口的头文件如下所示:

#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

主窗口的 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

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

【问题讨论】:

  • 您是否使用调试器查看它的段错误?我会用 nullptr 初始化那些 Dialog 指针,然后我会检查是否 (mDialog1 != nullptr)。
  • 是的,我做到了。我还根据您的建议更改了代码,但它仍然是一样的。下级停止了,因为它收到了来自操作系统的信号。信号名称:SIGSEGV 信号含义:文件 qwidget.cpp 第 7914 行中的分段错误 Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(data->window_flags);它在方法 void QWidget::show()
  • 对不起,建议中有错误。问题是您应该检查 mDialog1 == nullptr。没有这个,它当然会崩溃,因为你调用了一个未初始化的 ponter。所以你应该将 mDialog1 和 mDialog2 初始化为 nullptr,然后将代码更改为 if (mDialog1 == nullptr)。这样,如果指针为null,你就初始化它并创建对应的类。
  • 你是对的。它现在起作用了。结合下面的答案,我明白我做错了什么。谢谢。

标签: qt segmentation-fault dialog


【解决方案1】:

首先,它与 Qt 无关。这是关于您的实现:在您的构造函数中,我没有看到初始化 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();

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多