2016-03-24 5 views
1

Моего Намерения
Qt Краш SIGSEGV Fault во время динамического добавления виджетов ScrollArea (ui-> scrollArea-> setWidget (...))

  • Я хочу, чтобы создать и добавить QWidget в scrollArea.
    Затем

  • создать и установить grid layout для этого QWidget.

  • Затем восполняет grid layout с push buttons каждым из которых есть текст, значение которого происходит от входа int* array.

Обзор Мой код:
У меня есть QDialog приложение с UI form.
В моей форме пользовательского интерфейса я добавил 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.
Я также обновил название вопроса соответственно.

+0

'ui-> scrollArea' или' ui' NULL или underfined. Поместите остальную часть кода. Или просто повторите его снова и найдите, где вы могли потерять определенные значения после первого вызова. – StahlRat

+0

У вас есть сообщение об ошибке? Вы пытались отлаживать шаг за шагом, проверяя переменные? – Ilya

+0

@llya crash message Программа неожиданно завершилась. Я отлаживал шаг за шагом и обнаружил, где он разбился. – AlirezaK

ответ

0

Вы добавили адрес локальных объектов в качестве параметра.

Здесь вы создаете массив объектов, которые являются локальными для этой функции

QPushButton* pushButtons=new QPushButton[size]; 

И здесь вы передаете свой адрес, который будет в конечном счете недействительным после функции закончилась

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

Edit: Попробуйте

for(int i=0;i<size;i++) 
{ 
    QPushButton* pushButtons=new QPushButton; 
    pushButtons=new QPushbutton; 
    ... 
    gl->addWidget(pushButtons,(int)floor(i/3),i%3); 
} 
Смежные вопросы