Qt的:小工具方法addButtons()根据需要,不工作 [英] Qt: Widget method addButtons() does NOT work as needed

查看:178
本文介绍了Qt的:小工具方法addButtons()根据需要,不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用QT5上的Windows7(初级)。结果
在我的应用程序的主窗口中我要显示和删除一些个按钮。

I am using Qt5 (beginner) on Windows7.
In the main window of my app I want to display and remove some push-buttons.

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 类是在这里:

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 ,我得到显示所有的按钮,但他们的缩水,微小或东西...:结果

Problem is: when I click on add_buttons, I get all buttons displayed, but they are shrunk, tiny or something... :

OTOH ...如果我删除 addButtons()注释调用构造函数(因此从构造函数中调用),其结果是确定的:结果

OTOH... if I remove the comment from addButtons() call in the constructor (hence calling from within the constructor), the result is ok:

所以,最后我有2个问题:结果
1)的如何修复code,能够正确地添加这些按钮(当按下 add_buttons )?结果
2) deleteButtons()方法好吗?

So, finally I have 2 questions:
1) How to fix the code to be able to add those buttons properly (when add_buttons is clicked)?
2) Is the deleteButtons() method ok?

推荐答案

编辑:

一些更多的测试后(不看源$ C ​​$ C,但怀疑它必须是安全的删除按钮,否则事情会变脆),我已经实现removeButtons如下:

After some more testing (without looking at the source code, but suspecting that it must be safe to delete button, else things would be brittle), I've implemented removeButtons as follows:

void ButtonWidget::deleteButtons()
{
    while(myLayout->count())
    {
        delete myLayout->itemAt(0)->widget();
    }
}

这工作的,它证明了删除小工具还删除小部件从它的父,并与母公司关联的布局(由迷上了当一个孩子widget被删除,插槽)。以上code证实了这一点,因为数(),它指的是布局的项目数,减少到零(和这些项目布局由布局管理)。 takeAt(X)不会被调用,而不必是 - 简单地删除小部件(按钮)。 Wholla!

This works, and it proves that deleting a widget also removes the widget from it's parent, and layouts associated with the parent (by slots hooked up to when a child widget is deleted). The above code confirms this, as count(), which refers to number of layout items, decrease to zero (and those layout items are managed by the Layout). takeAt(x) is never called, and doesn't need to be - simply delete the widgets (buttons). Wholla!

原来的答案

正如我在其他文章中提到,你只需要删除按钮(它从其父自动删除)。然而,如果小窗口加入到布局,该布局的父成为小部件的亲和相关QLayoutItem创建由所述布局自身管理。到了删除按钮,最安全的方式是采取所有版面项目(所有权接受者的责任),删除相关部件的每个项目,以及删除的各个项目。我会努力从源头上除了找到相关的参考...

As mentioned in my other post, you only need to delete the buttons (it is removed from its parent automatically). However, if a widget was added to a layout, the parent of that layout becomes the parent of the widget, and an associated QLayoutItem is created that is managed by the layout itself. To the delete the buttons, the safest way is to take all the layout items (ownership the taker's responsibility), delete each items associated widget, and the delete each item. I'll try and find relevant references apart from the sources...

以下code工作:

//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();
}

您需要启用你的配置(.PRO)C ++ 11获得lambda表达式的工作。

You need to enable c++11 in your config (.pro) to get the lambdas working.

CONFIG += c++11

我用QHBoxLayout,负责为您的按钮,因为它更好的模型,你想要什么。虽然严格没有必要的,我是从makeArea返回的unique_ptr主,因为它没有父母,我不知道它是否得到了一些家长,因为它是第一个部件创建,但显示的unique_ptr意向。

I've used QHBoxLayout for your buttons, as it better models what you want. Although strictly not necessary, I'm returning unique_ptr from the makeArea in main, as it has not parent, I'm not sure whether it gets some parent because it is the first widget created, but unique_ptr shows intent.

请注意:

显然布局项目不是小部件的父,但与布局本身相关联的窗口小部件是属于其布局项目部件的父

Apparently the layout item is not the parent of the widget, but the widget associated with the layout itself is the parent of widgets belonging to its layout item.

这篇关于Qt的:小工具方法addButtons()根据需要,不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆