如何从QWidget正确删除项目

时间:2020-07-03 12:28:00

标签: 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(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()函数中删除所有小部件,然后用新项目填充小部件。

问题是,删除现有项目后,新项目没有从上到下填充,而是从中间开始出现。

1 个答案:

答案 0 :(得分:2)

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

您应该将小部件创建为指针,并为其分配良好的育儿功能,未父级的小部件将创建一个新窗口。你应该做这样的事情。

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),因为您可以查询对象,但是为了清楚起见,我将它们添加到了那里。

最后一个示例适用于您的方案,您可以将“项目小部件”存储在列表中,或查询它们的布局,当您需要删除它们时,只需这样做,然后将新的小部件添加到布局中即可。 当然,您可以使用任何一种布局,我仅以垂直为例。