【问题标题】:Dynamic QGridLayout of QPushButton c++QPushButton c++的动态QGridLayout
【发布时间】:2014-09-24 11:48:22
【问题描述】:

在花费数小时寻找解决方案后,为了构建一个动态添加和删除按钮的网格,它不会在转到下一页时删除以前的按钮。

我在这里进行了搜索,找到了“一些”解决方案,但它们不起作用。

这是我的代码。

这是用 myQpushButtons 填充向量的代码(在按钮上添加了我需要的 3 个方法)

QString famId = ui->comboBox->itemData(index).toString();
if (vectButtons.size() > 0)
{
    vectButtons.clear();
}
int totalPerPage = gridRow * gridColl;
int countPage = 0;
int totalButtons = 0;
double counterProd = 1.0;
qDebug() << idbConnect.get_Familia(famId)->get_FamProd()->count();
for (pair<QString, Produto> prod : idbConnect.get_Familia(famId)->get_FamProd()->toStdMap())
{
    if (counterProd == totalPerPage)
    {
        countPage++;
        counterProd = 2.0;
        buttons = new myQPushButton();
        buttons->setText("Proximo");
        buttons->set_Tipo(1);
        buttons->set_Pagina((totalPerPage * countPage));
        connect(buttons,SIGNAL(released()),this,SLOT(handleButton()));
        vectButtons.push_back(buttons);
        // #####################################################
        buttons = new myQPushButton();
        buttons->setText("Anterior");
        buttons->set_Tipo(1);
        buttons->set_Pagina((totalPerPage * (countPage - 1)));
        connect(buttons,SIGNAL(released()),this,SLOT(handleButton()));
        vectButtons.push_back(buttons);
        // #####################################################
    }
    buttons = new myQPushButton();
    buttons->setText(prod.second.get_Nome());
    buttons->set_id_Prod(prod.first);
    buttons->set_Tipo(0);
    connect(buttons,SIGNAL(released()),this,SLOT(handleButton()));
    vectButtons.push_back(buttons);
    counterProd++;
    totalButtons++;
}
fillGrid(0);

这是填充网格的方法,然后添加到 thw 小部件的布局中

void MainWindow::fillGrid(int start)
{
grid = new QGridLayout;
for (int i = 0; i < gridRow; i++)
{
    for (int y = 0; y < gridColl; y++)
    {
        grid->addWidget(vectButtons.at(start),i,y);
        start++;
    }
}
ui->widget->setLayout(grid);
ui->widget->repaint();
ui->widget->show();
}

当我单击下一个或上一个时,它会被调用,以用新按钮填充网格。

void MainWindow::replaceGrid(int start)
{
/*QLayout *temp;
temp = ui->widget->layout();
temp->deleteLater();
delete temp;
grid->deleteLater();
delete grid;
ui->widget->layout()->deleteLater();
delete ui->widget->layout();*/
removeLayout(ui->widget);
ui->widget->layout()->deleteLater();
delete ui->widget->layout();
grid = new QGridLayout;
for (int i = 0; i < gridRow; i++)
{
    for (int y = 0; y < gridColl; y++)
    {
        if (start < vectButtons.size())
        {
            grid->addWidget(vectButtons.at(start),i,y);
            start++;
        }
    }
}
ui->widget->setLayout(grid);
ui->widget->repaint();
ui->widget->show();
}

这调用了其他方法,从小部件的布局(在本例中为网格)中删除所有项目,因为我在这个网站上看到了这个解决方案,说我们需要在删除布局之前删除所有项目小部件。

void MainWindow::removeLayout(QWidget* widget)
{
QLayout* layout = widget->layout();
if (layout != 0)
{
    QLayoutItem *item;
    while ((item = layout->takeAt(0)) != 0)
    {
        layout->removeItem(item);
    }
    delete layout;
}
}

但这不起作用,当我单击下一步(删除所有以前的按钮并从矢量中添加新按钮)时,如果我要删除它们,它将在新按钮不知道为什么的情况下将它们放在删除布局并添加新布局。

对此有什么想法吗?

【问题讨论】:

    标签: c++ qt qt5 qwidget qgridlayout


    【解决方案1】:

    您从布局中删除了项目,但没有删除按钮。如果你想完全摆脱这些按钮,你也必须删除它们。或者你可以隐藏它们,如果你不想删除它们(你可以这样做,如果你这样做,没有必要从布局中删除它们,是吗?)。否则,它们将在其父小部件中可见。您可以使用QLayoutItem::widget 获取小部件。

    也许对您来说更好的解决方案是使用QStackedLayout。这是文档中的一个示例:

    QWidget *firstPageWidget = new QWidget;
    QWidget *secondPageWidget = new QWidget;
    QWidget *thirdPageWidget = new QWidget;
    
    QStackedLayout *stackedLayout = new QStackedLayout;
    stackedLayout->addWidget(firstPageWidget);
    stackedLayout->addWidget(secondPageWidget);
    stackedLayout->addWidget(thirdPageWidget);
    
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addLayout(stackedLayout);
    setLayout(mainLayout);
    

    并使用QComboBox 更改stackedlayout 的页面:

    QComboBox *pageComboBox = new QComboBox;
    pageComboBox->addItem(tr("Page 1"));
    pageComboBox->addItem(tr("Page 2"));
    pageComboBox->addItem(tr("Page 3"));
    connect(pageComboBox, SIGNAL(activated(int)),
            stackedLayout, SLOT(setCurrentIndex(int)));
    

    如果你真的需要从布局中删除按钮,这里有一个小例子:

    centralWidget()->setLayout(new QVBoxLayout);
    for(int i = 0; i < 10; i++)
    {
        centralWidget()->layout()->addWidget(new QLabel(QString("LABEL%1").arg(i)));
    }
    QLayoutItem *item;
    while((item= centralWidget()->layout()->takeAt(0)) != 0)
    {
    //        item->widget()->setHidden(true);
        item->widget()->setParent(0); // you can use this or setHidden... up to you
        delete item;
    }
    

    【讨论】:

    • 那行不通,因为它可以有 1 页或 10 页,并且在程序期间他们可以为同一个系列添加更多按钮。假设该系列的最后一页充满了按钮,我添加了一个新页面,我还需要为它创建一个新页面。通过删除布局并添加新布局将非常适合我想要的。关于我不想要的删除按钮,我尝试了它并删除了我只想将它从布局中删除的矢量按钮的信息,但仍然在内存中
    • @user3310091 然后从布局中删除按钮似乎毫无意义。只需隐藏您不需要可见的按钮即可。当您从布局中删除小部件时,它们仍将保持可见。当您将它们添加到布局时,它会自动重新设置它们。当您从布局中删除它们时,它们将在父级中保持可见。你仍然需要隐藏它们。我只是不明白从布局中删除它们的意义。也许如果网格布局内的位置存在问题。
    • 删除它们不是更容易吗?!?!我现在可以需要它们,但不是在一天的剩余时间里,或者我可能整天都需要它们。这就是为什么我想将它们放在矢量上,并且仅在我需要它们可见时才调用它们。这就是为什么我试图从布局中删除它们(进入小部件->布局的网格)并为下一页创建一个新网格
    • @user3310091 如果你真的需要从布局中删除它们,那么就这样做吧。但请记住也要隐藏它们(button-&gt;setHidden(true);layoutItem-&gt;widget()-&gt;setHidden(true);)。即使它们不在布局内,它们仍将保持可见。您无需将小部件放入布局中即可使其可见。
    • 那么隐藏和可见的区别是什么?我需要这个来尽可能少地占用内存,而且速度很快,这就是为什么我要尝试但内存上的所有按钮,所以他不会在每次我需要它们时创建它们,我只是有一个包含所有按钮的向量信息(包括需要时的下一个和上一个按钮)。这就是为什么我想创建只有 25 个按钮(例如)的网格,并且只有它们在网格中,其余的在内存中,当我需要添加到网格上并放置它们时。这就是我动态创建和删除网格的原因,至少尝试一下呵呵:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 2018-04-23
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多