c++ 为什么使用QSlider调用创建时QLabel没有动态创建?

dced5bon  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(142)

我是QtCreator的新手。我正在尝试做一个滑块,当我移动滑块时动态地删除和重新创建标签。当我从构造函数调用它时,我能够动态地创建标签,但由于某种原因,当我通过移动滑块做同样的事情时,它不起作用。
我打算每次滑块被移动所有的标签被删除,并创建新的。我不确定是否是删除过程,搞乱了这一点或其他东西。当我在调试模式下运行它似乎是新的QLabel*插入到labels_?向量,但由于某种原因,他们是不可见的。
下面是我的代码:
mainwindow.cpp:

#include "mainwindow.hh"
#include "ui_mainwindow.h"
#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->horizontalSlider->setRange(1,10);
    ui->horizontalSlider->setValue(5);

    connect(ui->horizontalSlider, &QSlider::sliderMoved, this, &MainWindow::move_slider);

    // This works
    //create_label(50);

    // This works
//    for (auto i = 0 ; i < ui->horizontalSlider->value(); i++) {
//        labels_.push_back(create_label(i*item_width_));
//    }
}

MainWindow::~MainWindow()
{
    delete ui;
 }

QLabel* MainWindow::create_label(int x)
{
    QLabel* label = new QLabel(ui->frame);
    label->setGeometry(x, 0, item_width_, item_width_);
    label->setText(QString::number(ui->horizontalSlider->value()));
    return label;
}

// This method is called when silder moves. It seems to remove labels,
// but does not make new labels.
void MainWindow::move_slider()
{
    // Remove labels and reset
    for (QLabel* label: labels_) {
        delete label;
    }
    labels_.clear();

    // Create labels
    for (auto i = 0 ; i < ui->horizontalSlider->value(); i++) {
        labels_.push_back(create_label(i*item_width_));
    }
}

mainwindow.hh

#ifndef MAINWINDOW_HH
#define MAINWINDOW_HH

#include <QMainWindow>
#include <QLabel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    int item_width_ = 20;

    std::vector<QLabel*> labels_;

    QLabel* create_label(int x);

    void move_slider();

    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HH

如调试窗口所示,移动滑块后标签的内容:

**编辑:**我尝试从move_slider()断开滑块,而是创建PushButton并将其连接到:

//connect(ui->horizontalSlider, &QSlider::sliderMoved, this, MainWindow::move_slider);
connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::move_slider);

这也会在单击时调用方法,并将标签移除到不可见的位置,但不返回它们。
我尝试的另一件事是在构造函数中运行它,而不需要按任何按钮或移动滑块:

// Create labels
for (auto i = 0 ; i < ui->horizontalSlider->value(); i++) {
    labels_.push_back(create_label(i*item_width_));
}

// Remove labels and reset
for (QLabel* label: labels_) {
    delete label;
}
labels_.clear();

// Create labels again
for (auto i = 0 ; i < ui->horizontalSlider->value(); i++) {
    labels_.push_back(create_label(i*item_width_));
}

它正确地显示了标签,所以我认为我的删除应该起作用(至少上面这行看起来在构造函数中起作用),但是仅仅是作为方法或构造函数的一部分似乎是新标签是否可以显示的关键区别,即使它不应该显示。

l0oc07j2

l0oc07j21#

引用自QWidget构造函数的Qt文档:
如果向已经可见的小部件添加子小部件,则必须显式显示子小部件以使其可见。
只需将label->setVisible(true);添加到create_label方法中:

QLabel* MainWindow::create_label(int x)
{
    QLabel* label = new QLabel(ui->frame);
    label->setGeometry(x, 0, item_width_, item_width_);
    label->setText(QString::number(ui->horizontalSlider->value()));
    label->setVisible(true);  // Add this
    return label;
}

它在构造函数中工作,因为此时窗口不可见。

相关问题