2

Qtを始めたばかりです。カスタム データ型の表示/編集に使用できるカスタム ウィジェットを備えた GUI を作成したいと考えています。また、これらのウィジェットを動的に作成/破棄できるようにしたいと考えています (基になるデータを破棄することなく)。

dataContainerデータ項目のリスト ( ) をメインの Window クラスに格納し、このポインターを格納するdataContainerウィジェット ( ) のコンストラクターにポインターを渡すことで、これを達成しようとしましたcustomWidget。次にcustomWidget、このポインターを介して基になるデータを変更できます。

以下のコードにより、ユーザーは繰り返しdataContainerインスタンスをリストに追加し、それぞれの「名前」を編集できます。これを実行すると、実際に名前を編集しない限りすべて正常に動作しますが、名前を編集してから [追加] ボタンをクリックすると、segfault が発生します。この segfault は、 during のデストラクタ中に発生customWidgetdelete myWidget;ますWindow::add()

2 つの質問:

  1. このコードがクラッシュするのはなぜですか? このようなウィジェットを動的に作成/破棄することは許可されていませんか?
  2. これを達成するためのより適切な方法はありますか?

ここに欠けている基本的なものがある場合はお詫びしますが、多くのフォーラムやチュートリアルを行ったり来たりしましたが、役立つものは何も見つかりませんでした.

main.cpp

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

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Window mainWindow;
    mainWindow.show();
    return app.exec();
}

window.h

#ifndef WINDOW_H
#define WINDOW_H

#include <QWidget>
#include "customwidget.h"

class Window : public QWidget {
  Q_OBJECT
  public:
    Window();

  public slots:    
    void add();    

private:

  // the main data structure
  QList<dataContainer> dataList;

  // the widget that displays the custom data
  customWidget *myWidget;     

  QVBoxLayout *mainLayout;
  QPushButton *addButton;

};

#endif

ウィンドウ.cpp

#include <QtGui>
#include "window.h"

Window::Window(){

  // start with a single piece of data in the list
  dataContainer newData;
  dataList.append(newData);

  // create layout container
  mainLayout = new QVBoxLayout(this);
  mainLayout->setAlignment(Qt::AlignTop);

  // make the Add button, and connect its clicked() SIGNAL
  // to our add() SLOT
  addButton=new QPushButton(tr("Add"),this);
  connect(addButton,SIGNAL(clicked()),this,SLOT(add()));
  mainLayout->addWidget(addButton);  

  // create a custom widget to display our data and
  // give it a pointer to the data it will display/modify
  myWidget = new customWidget(this,&(dataList.last()) );
  mainLayout->addWidget(myWidget);

  setLayout(mainLayout);   

}

void Window::add(){

  // create a new piece of data, and add to the list
  dataContainer newData;
  dataList.append(newData);

  // debug: show the current list
  qDebug() << "Data List(" << dataList.size() << ")";
  for (int i=0;i<dataList.size();i++){
    qDebug() << dataList[i].getName().c_str();
  }

  // delete the old widget
  delete myWidget;

  // and make a new widget with the new data
  myWidget = new customWidget(this,&(dataList.last()) );
  mainLayout->addWidget(myWidget);   

}
#include "window.moc"

customwidget.h

#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H

#include <QWidget>
#include <QtGui>
#include <string>

class dataContainer {
  private:

    std::string name;

  public:
    dataContainer(){name="oooh";};
    std::string getName()const{return name;};
    std::string setName(const std::string& n){name=n;};

};

class customWidget : public QWidget {
  Q_OBJECT

  private:
    dataContainer *data;

  public slots:
    void nameChangedSlot(const QString&);

  public:
    customWidget(QWidget *parent,  dataContainer *d);

};
#endif

customwidget.cpp

#include "customwidget.h"

customWidget::customWidget(QWidget *parent,  dataContainer *d) : QWidget(parent) {

  // store a pointer to the data that we want to alter
  data = d;

  // create an edit box and initialize it with the data name
  QVBoxLayout *mainLayout=new QVBoxLayout(this);
  QLineEdit *edit=new QLineEdit(QString::fromStdString(data->getName()),this);
  mainLayout->addWidget(edit);

  connect(edit,SIGNAL(textChanged(const QString&)),this,SLOT(nameChangedSlot(const QString&)));

}

void customWidget::nameChangedSlot(const QString& name){

  // alter the contents of our data based on the changed string
  data->setName(name.toStdString());

}

#include "customwidget.moc"
4

1 に答える 1

3

レイアウトに追加されたウィジェットは直接削除できません。代わりに、特定のウィジェットと対応するレイアウト アイテムをレイアウトから削除する以下のコードを試すことができます。

QLayoutItem* item;
while ( ( item = mainLayout->takeAt( 0 ) ) != NULL )
{
    if(item->widget() == myWidget){
        delete item->widget();
        delete item;
    }
}
于 2013-01-09T07:43:04.033 に答える