首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Qt:小部件方法addButtons()不能按需要工作

Qt:小部件方法addButtons()不能按需要工作
EN

Stack Overflow用户
提问于 2016-04-21 14:40:27
回答 2查看 228关注 0票数 0

我在Windows7上使用Windows7(初学者)。

在我的应用程序的主窗口,我想显示和删除一些按钮。

代码语言:javascript
运行
复制
widget = new ButtonWidget(ui->frame); // frame is a QScrollArea
connect(ui->addBtns,    SIGNAL(clicked()), widget, SLOT(addButtons()));
connect(ui->deleteBtns, SIGNAL(clicked()), widget, SLOT(deleteButtons()));

ButtonWidget类在这里:

代码语言:javascript
运行
复制
ButtonWidget::ButtonWidget(QWidget * parent) : QWidget(parent)
{
   //addButtons();
}

void ButtonWidget::addButtons()
{
   QStringList texts{"1\nok", "2\nok", "3\nok", "4\nok", "5\nok", "6\nok"};
   gridLayout = new QGridLayout;
   for(int i = 0; i < texts.size(); i++)
   {
      QPushButton * button = new QPushButton(texts[i]);
      gridLayout->addWidget(button, i / 5, i % 5);
   }
   setLayout(gridLayout);
}

// I'm not sure this method/function is ok... :(
void ButtonWidget::deleteButtons()
{
    QLayoutItem * child;
    while((child = gridLayout->takeAt(0)) != 0)
    {
        gridLayout->removeWidget(child->widget());
        delete child->widget();
        delete child;
    }
    delete gridLayout;
}

问题是:当我点击add_buttons时,我会显示所有的按钮,但它们都是缩小的、微小的之类的.:

奥托..。如果我从构造函数中的addButtons()调用中删除注释(因此从构造函数中调用),则结果是ok:

最后,我有两个问题:

1)如何修复代码以正确添加这些按钮(单击add_buttons时)?

2) deleteButtons()方法可以吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-21 16:56:23

编辑:

经过一些更多的测试(没有查看源代码,但怀疑删除按钮必须是安全的,否则就会变得很脆弱),我实现了removeButtons如下:

代码语言:javascript
运行
复制
void ButtonWidget::deleteButtons()
{
    while(myLayout->count())
    {
        delete myLayout->itemAt(0)->widget();
    }
}

这是可行的,而且它也证明了删除一个小部件也会从它的父部件中移除小部件,以及与父部件相关联的布局(通过删除子小部件时连接到的插槽)。上面的代码确认了这一点,因为count() (指布局项的数量)减少到零(这些布局项由布局管理)。takeAt(x)从未被调用,也不需要被调用--只需删除小部件(按钮)。Wholla!

原始答案

正如我在另一篇文章中提到的,您只需要删除按钮(它将自动从其父节点中删除)。但是,如果将一个小部件添加到布局中,则该布局的父级将成为该小部件的父级,并创建一个由布局本身管理的关联QLayoutItem。要删除按钮,最安全的方法是获取所有布局项(拥有接收者的责任)、删除每个相关的小部件和删除每个项目。我会努力找到相关的参考资料,除了资料来源.

以下代码工作:

代码语言:javascript
运行
复制
//ButtonWidget.h
#include <QWidget>
#include <QScrollArea>
#include <QHBoxLayout>

class ButtonWidget : public QScrollArea
{
    Q_OBJECT

  public:
    ButtonWidget(QWidget *parent = 0);
    ~ButtonWidget();
    void addButtons();
    void deleteButtons();
  private:
    QHBoxLayout* myLayout;
};

//ButtonWidget.cpp

#include "ButtonWidget.h"
#include <QGridLayout>
#include <QPushButton>
#include <QLayoutItem>

ButtonWidget::ButtonWidget(QWidget * parent) :
  QScrollArea(parent),
  myLayout(new QHBoxLayout(this))
{
}

ButtonWidget::~ButtonWidget()
{
}

void ButtonWidget::addButtons()
{
   QStringList texts{"1\nok", "2\nok", "3\nok", "4\nok", "5\nok", "6\nok"};

   for(int i = 0; i < texts.size(); i++)
   {
      myLayout->addWidget(new QPushButton(texts[i]));
   }
}

void ButtonWidget::deleteButtons()
{
    QLayoutItem * child;

    while((child = myLayout->takeAt(0)) != 0)
    {
      delete child->widget();
      delete child;
    }
}

#include "ButtonWidget.h"
#include <QApplication>
#include <QScrollArea>
#include <QPushButton>
#include <QGridLayout>
#include <QHBoxLayout>
#include <memory>

std::unique_ptr<QScrollArea> makeArea()
{
  std::unique_ptr<QScrollArea> area(new QScrollArea);
  auto layout = new QGridLayout(area.get());
  auto addButton  = new QPushButton("Add");
  auto removeButton  = new QPushButton("Remove");
  layout->addWidget(addButton, 0, 0);
  layout->addWidget(removeButton, 0, 1);
  auto btnWidget = new ButtonWidget;
  layout->addWidget(btnWidget,1,0,1,2);


  QObject::connect(addButton, &QPushButton::clicked, [=]()
  {
    btnWidget->addButtons();
  });

  QObject::connect(removeButton, &QPushButton::clicked, [=]()
  {
    btnWidget->deleteButtons();
  });
  return move(area);
}

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  auto area = makeArea();
  area->show();
  return a.exec();
}

您需要在您的配置中启用c++11 (.pro)来使lambda工作。

代码语言:javascript
运行
复制
CONFIG += c++11

我用QHBoxLayout作为你的按钮,因为它能更好地模拟你想要的东西。虽然严格来说没有必要,但我主要是从unique_ptr返回makeArea,因为它没有父级,所以我不确定它是否得到了一些父部件,因为它是创建的第一个小部件,但是unique_ptr显示了意图。

注意:

显然,布局项不是小部件的父级,但是与布局本身关联的小部件是属于其布局项的小部件的父项。

票数 1
EN

Stack Overflow用户

发布于 2016-04-21 15:29:13

首先,我建议

代码语言:javascript
运行
复制
gridLayout = new QGridLayout(this);

在构造函数中。您不需要删除所有网格,再次创建网格,并将其设置为布局,这时您只需删除其内容(例如,删除按钮),然后再填充它。

编辑:Werner的注释:不需要设置布局。事实上,它有一个父部件,这意味着它设置了自己。

问题是,您不修改addButtons(),您将在不知道按钮去向的情况下替换前面的按钮。

另外,尝试给QPushButton一个父级:

代码语言:javascript
运行
复制
new QPushButton(texts[i],this);

关于第二点:Removing widgets from QGridLayout

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36772942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档