Qt 如何从QWidget中正确删除项目

Qt 如何从QWidget中正确删除项目,qt,qt5,Qt,Qt5,这是用于填充和删除QWidget中的项的代码 class ShowCommands : public QWidget { private: QWidget wdg; QVBoxLayout m_layout; QScrollArea* m_area; QWidget m_contents; QVBoxLayout m_contentsLayout; bool isWrite; public: ShowCommands(QWidge

这是用于填充和删除QWidget中的项的代码

class ShowCommands : public QWidget
{
private:
    QWidget wdg;
    QVBoxLayout m_layout;
    QScrollArea* m_area;
    QWidget m_contents;
    QVBoxLayout m_contentsLayout;
    bool isWrite;
    
public:
    ShowCommands(QWidget *parent = nullptr);
    void showWindow();
    void setParent(QWidget* par);
    void AddCommand(std::string stdstrCommand);
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ShowCommands::ShowCommands(QWidget *parent) :  QWidget(parent)
{
    isWrite = true; 
    m_area = new QScrollArea;   
    m_contents.setLayout(&m_contentsLayout);
    m_layout.addWidget(m_area);
    m_area->setWidget(&m_contents);
    m_contentsLayout.setSizeConstraint(QLayout::SetMinimumSize);
    wdg.setLayout(&m_layout);
    wdg.setFixedWidth(650);
    wdg.setWindowTitle("Commands");
    wdg.setWindowFlags(Qt::Window
    | Qt::FramelessWindowHint);
    wdg.hide();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ShowCommands::showWindow()
{   
    if (isWrite == false)
    {
        if (m_contentsLayout.layout() != NULL)
        {
            QLayoutItem* item;
            while ((item = m_contentsLayout.layout()->takeAt(0)) != NULL)
            {
                delete item->widget();
                delete item;
            }           
        }
        isWrite = true;
        wdg.show();
        // AddCommand() function is called now multiple times and items are populated.
    }
    else
    {
        isWrite = false;
        wdg.hide();
    }
}


void ShowCommands::AddCommand(std::string stdstrCommand)
{   
    if (isWrite)
    {    
     QLabel *label = new QLabel;
     label->setText(stdstrCommand.c_str());
     m_contentsLayout.addWidget(label);
    }
}
在showWindow函数中,首先删除小部件的所有项目,然后用新项目填充小部件


问题是,在我删除现有项后,新项不会从上到下填充,而是从中间开始显示。

我看到您的代码存在许多问题,其中一些问题使其难以阅读,但无论如何,我认为这里的主要问题是如何正确创建这些项

您应该将小部件创建为指针,并为它们指定良好的父项,未命名的小部件将创建一个新窗口。你应该这样做

class MyWidget: public QWidget
{
Q_OBJECT
public;
    MyWidget(QWidget *parent=nullptr) : QWidget(parent)
    {
        w1=new QWidget(this);
        
    }
private:
    class QWidget *m_w1;
}
这样,您将拥有一个子小部件,该小部件将在同一窗口中相对于您绘制。您可以将布局添加到小部件,然后将小部件添加到其中,以便它为您处理位置。即:

class MyWidget: public QWidget
{
Q_OBJECT
public;
    MyWidget(QWidget *parent=nullptr) : QWidget(parent)
    {
        //passing this to the construct assign layout to 'this' widget
        QVBoxLayout *verticalLayout=new QVBoxLayout(this);
        
        w1=new QWidget(this);
        w2=new QWidget(this);
        
        verticalLayout->addWidget(w1);
        verticalLayout->addWidget(w2);
        
    }
private:
    class QWidget *m_w1;
    class QWidget *m_w2;
}
在这种情况下,两个小部件将在分配给您的空间中一个接一个地显示。另外,分配给您的空间将取决于两个子小部件的特性,您可能会创建一些从QWidget派生的东西

关于QScrollArea,这个小部件应该与放置在“内部”的小部件一起使用,您应该将项目添加到该小部件的布局中。即:

class MyWidget: public QWidget
{
Q_OBJECT
public;
    MyWidget(QWidget *parent=nullptr) : QWidget(parent)
    {
        //passing this to the construct assign layout to 'this' widget
        QVBoxLayout *verticalLayout=new QVBoxLayout(this);
        
        m_scroll=new QScrollArea(this);
        
        verticalLayout->addWidget(m_scroll);
        
        m_containerwidget=new QWidget(this);
        
        //this sets our container widget as the inside's scrollarea widget
        m_scroll->setWidget(m_containerwidget);
        //if your widget will resize along the way you use this, in your case you do
        m_scroll->setWidgetResizable(true);

        m_containerLayout=new QVBoxLayout (m_containerwidget);

        m_w1=new QWidget(this);
        m_w2=new QWidget(this);
        
        m_containerLayout->addWidget(m_w1);
        m_containerLayout->addWidget(m_w2);
        
        
    }
private:
    class QScrollArea *m_scroll;
    class QWidget *m_containerwidget;
    class QVBoxLayout *m_containerLayout;
    class QWidget *m_w1,m_w2;
}
您通常不会在类中存储所有信息m_containerLaoyut,m_containerWidget,因为您可以查询对象,但为了清楚起见,我将它们添加到了那里

最后一个例子适用于您的场景,您可以将“items widget”存储在列表中,或者查询它们的布局,当您需要删除它们时,只需这样做,然后将新的添加到布局中。 当然你可以使用任何类型的布局,我使用垂直布局作为例子