Qt崩溃SIGSEGV动态添加小部件到scrollArea时出错(ui-> scrollArea-> setWidget(...))

时间:2016-03-24 18:00:19

标签: c++ qt crash

我的意图

  • 我想创建一个QWidget并添加到scrollArea
    然后

  • grid layout创建并设置QWidget

  • 然后填写grid layout,每个push buttons 有一个文本,其值来自输入int* array

我的代码概述:
我有一个QDialog应用程序UI form
在我的UI表单中,我使用scrollArea添加了QtDesigner 在我的程序中,当某些事件发生时,我调用以下函数:

void View::setUpBatteryTypes(int* array,int size)
{
    QGridLayout* gl=new QGridLayout();
    QWidget *viewport = new QWidget;
    viewport->setLayout(gl);
    qDebug()<<"debug test 1";
    ui->scrollArea->setWidget(viewport); //crashes here in 2nd call of func
    qDebug()<<"debug test 2";

    QPushButton* pushButtons=new QPushButton[size];
    for(int i=0;i<size;i++)
    {
        pushButtons[i].setText(QVariant(array[i]).toString());
        pushButtons[i].setMinimumSize(200,100);
        pushButtons[i].setMaximumSize(400,200);
        pushButtons[i].setStyleSheet("background-color: rgb(170,170,197);");
        gl->addWidget(&pushButtons[i],(int)floor(i/3),i%3);

    }  
}

问题
我的问题是,当我第一次在我的应用程序中调用函数setUpBatteryTypes时,一切正常,函数执行我打算做的事情。但是,当在我的应用程序中第二次调用该函数时,它会在两个qDebug()语句之间的注释行中崩溃。

<小时/> 这是我的代码
dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
public:
    void setUpBatteryTypes(int*,int);
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QGridLayout>
#include <QDebug>
#include <QPushButton>

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

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

void Dialog::setUpBatteryTypes(int* array,int size)
{

    QGridLayout* gl=new QGridLayout();
    QWidget *viewport = new QWidget;
    viewport->setLayout(gl );
    qDebug()<<"debug test 1";
    qDebug()<<ui->scrollArea->children();
    ui->scrollArea->setWidget(viewport);
    qDebug()<<ui->scrollArea->children();
    qDebug()<<"debug test 2";

    QPushButton* pushButtons=new QPushButton[size];

    for(int i=0;i<size;i++)
    {
        pushButtons[i].setText(QVariant(array[i]).toString());
        pushButtons[i].setMinimumSize(200,100);
        pushButtons[i].setMaximumSize(400,200);
        pushButtons[i].setStyleSheet("background-color: rgb(170,170,197);");
        gl->addWidget(&pushButtons[i],(int)floor(i/3),i%3);
    }
}

的main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog* w=new Dialog();
    w->show();
    int size=4;
    int* array=new int[size];
    for(int i=0;i<size;i++)
    {
        array[i]=i;
    }

    w->setUpBatteryTypes(array,size);
    w->setUpBatteryTypes(array,size);

    return a.exec();
}

dialog.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QScrollArea" name="scrollArea">
     <property name="widgetResizable">
      <bool>true</bool>
     </property>
     <widget class="QWidget" name="scrollAreaWidgetContents">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>380</width>
        <height>280</height>
       </rect>
      </property>
     </widget>
    </widget>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>


<小时/> 我调试了我的代码,它显示了一个SIGSEGV错误。
我也相应地更新了问题标题。

1 个答案:

答案 0 :(得分:0)

您将本地对象的地址添加为参数。

在这里创建一个对象数组,它是本函数的本地对象

QPushButton* pushButtons=new QPushButton[size];

在这里你传递了他们的地址,这个地址在函数结束后最终会无效

gl->addWidget(&pushButtons[i],(int)floor(i/3),i%3);

编辑: 尝试

for(int i=0;i<size;i++)
{
    QPushButton* pushButtons=new QPushButton;
    pushButtons=new QPushbutton;
    ...
    gl->addWidget(pushButtons,(int)floor(i/3),i%3);
}