为什么这段代码会在w.show()调用中出现段错误?

时间:2014-08-11 10:10:25

标签: c++ qt

主题说明了一切,这是代码:

我正在使用Windows 7 64位与qt-opensource-windows-x86-mingw482_opengl-5.3.1

我在下面发布了受影响的代码。调试崩溃时,我在main.cpp文件中的w.show()行上得到段错误

编辑: 抱歉忘记添加它,如果我注释掉该行,它不会崩溃:

//mainLayout->addLayout(oldLayout,0,0,1,1,Qt::AlignLeft);

然后核心显示主窗口的小部件,但是当我尝试向布局添加布局时,它会崩溃......

main.cpp中:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.cpp

#include <QLabel>
#include <QString>

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setupWidgets();    
}


void MainWindow::setupWidgets() {

    mainWidget = new QWidget;
    mainLayout = new QGridLayout;

    setupOld();    

    setCentralWidget(mainWidget);
    mainWidget->setLayout(mainLayout);
    mainLayout->addLayout(oldLayout,0,0,1,1,Qt::AlignLeft);
}

void MainWindow::setupOld() {
    oldLayout = new QGridLayout;

    oldX = new QDoubleSpinBox;
    oldX->setRange(minNum,maxNum);
    oldX->setDecimals(precision);
    oldX->setSuffix(suffix);

    oldY = new QDoubleSpinBox;
    oldY->setRange(minNum,maxNum);
    oldY->setDecimals(precision);
    oldY->setSuffix(suffix);

    oldZ = new QDoubleSpinBox;
    oldZ->setRange(minNum,maxNum);
    oldZ->setDecimals(precision);
    oldZ->setSuffix(suffix);

    QLabel lblX, lblY, lblZ;
    lblX.setText("Old X Coord: ");
    lblY.setText("Old Y Coord: ");
    lblZ.setText("Old Z Coord: ");

    oldLayout->addWidget(&lblX,0,0,1,1,Qt::AlignLeft);
    oldLayout->addWidget(oldX,0,1,1,1,Qt::AlignLeft);
    oldLayout->addWidget(&lblY,1,0,1,1,Qt::AlignLeft);
    oldLayout->addWidget(oldY,1,1,1,1,Qt::AlignLeft);
    oldLayout->addWidget(&lblZ,2,0,1,1,Qt::AlignLeft);
    oldLayout->addWidget(oldZ,2,1,1,1,Qt::AlignLeft);
}

2 个答案:

答案 0 :(得分:2)

我认为原因在于以下代码:

QLabel lblX, lblY, lblZ;
[..]
oldLayout->addWidget(&lblX,0,0,1,1,Qt::AlignLeft);

您可以在堆栈中创建标签对象,并在布局中使用它们。标签在执行MainWindow::setupOld()函数后删除,因此您的布局包含对已删除对象的引用。

要解决此问题,您需要像编写QDoubleSpinBox es那样创建从堆中分配内存的标签:

QLabel *lblX = new QLabel("Old X Coord: ");
[..]
oldLayout->addWidget(lblX,0,0,1,1,Qt::AlignLeft);

答案 1 :(得分:0)

以下作品。请注意我如何考虑重复代码,将所有对象作为MainWindow的直接成员,并利用构造函数中的初始化列表。

如果您不想使用其他功能(停靠区域,状态栏等),则不必使用QMainWindow 。在下面的代码中,您可以轻松地将QMainWindow替换为QWidget,并执行以下其他更改:

  1. this上设置布局,而不是m_central

  2. 删除setCentralWidget来电。

  3. #include <QApplication>
    #include <QMainWindow>
    #include <QLabel>
    #include <QGridLayout>
    #include <QDoubleSpinBox>
    
    class MainWindow : public QMainWindow {
       QWidget m_central;
       QGridLayout m_centralLayout;
       QDoubleSpinBox m_oldX, m_oldY, m_oldZ;
       QLabel m_lblX, m_lblY, m_lblZ;
    public:
       MainWindow(QWidget * parent = 0, Qt::WindowFlags flags = 0);
    };
    
    MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) :
       QMainWindow(parent, flags),
       m_centralLayout(&m_central),
       m_lblX("Old X Coord: "),
       m_lblY("Old Y Coord: "),
       m_lblZ("Old Z Coord: ")
    {
       QList<QDoubleSpinBox*> spins;
       spins << &m_oldX << &m_oldY << &m_oldZ;
       int i = 0;
       foreach (QDoubleSpinBox * spin, spins) {
          spin->setRange(0.0, 1.0);
          spin->setDecimals(3);
          spin->setSuffix(" km");
          m_centralLayout.addWidget(spin, i++, 1);
       }
    
       m_centralLayout.addWidget(&m_lblX, 0, 0);
       m_centralLayout.addWidget(&m_lblY, 1, 0);
       m_centralLayout.addWidget(&m_lblZ, 2, 0);
    
       setCentralWidget(&m_central);
    }
    
    int main(int argc, char *argv[])
    {
       QApplication a(argc, argv);
       MainWindow w;
       w.show();
       return a.exec();
    }