gpt4 book ai didi

c++ - 在 Qt 中动态创建/销毁自定义小部件

转载 作者:搜寻专家 更新时间:2023-10-31 01:51:05 26 4
gpt4 key购买 nike

我刚开始使用 Qt。我想制作一个带有自定义小部件的 GUI,可用于显示/编辑我的自定义数据类型。我还希望能够动态地创建/销毁这些小部件(而不破坏底层数据)。

我试图通过在主窗口类中存储我的数据项列表 (dataContainer) 并将指向 dataContainer 的指针传递给我的小部件 (customWidget) 的构造函数,它存储此指针。然后 customWidget 可以通过这个指针改变底层数据。

下面的代码允许用户将 dataContainer 实例重复添加到列表中并编辑它们的每个“名称”。当我运行它时,只要我实际上不编辑名称,一切都正常,但如果我编辑名称然后单击“添加”按钮,我会得到一个段错误。此段错误发生在 Window::add()delete myWidget; 期间 customWidget 的析构函数期间。

两个问题:

  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

window.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"

最佳答案

不能直接删除添加到布局的小部件。相反,您可以尝试使用以下代码从布局中删除特定的小部件和相应的布局项:

QLayoutItem* item;
while ( ( item = mainLayout->takeAt( 0 ) ) != NULL )
{
if(item->widget() == myWidget){
delete item->widget();
delete item;
}
}

关于c++ - 在 Qt 中动态创建/销毁自定义小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14227155/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com