我开始学习使用qt编程,并开始熟悉该库,并开始编写简单的小程序。这些计划之一是创建QLabel,每次按下按钮时应将其添加到应用程序中,但是我不明白为什么它们不出现。这是代码:

文件.h:

class Base : public QWidget
{
    Q_OBJECT
public:
    explicit Base(QWidget *parent = 0);
    ~Base();

public slots:
    void AddWidget();

private:
    QVBoxLayout *Vlayout;
};

文件.cpp
Base::Base(QWidget *parent)
    : QWidget(parent)
{
    Vlayout=new QVBoxLayout(this);

    QPushButton *l=new QPushButton("+",this);

    Vlayout->addWidget(l);

    connect(l,SIGNAL(clicked()),this,SLOT(AddWidget()));
}

Base::~Base()
{}

void Base::AddWidget(){

    Vlayout->addWidget(new QLabel("Added",this));
    Vlayout->update();
}

非常感谢!

最佳答案

OPs代码中必须缺少某些内容。

另外,我认为不需要Vlayout->update()的调用。

我做了一个MCVE来演示:
testQWidgetAdd.cc:

// Qt header:
#include <QtWidgets>

// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QWidget qWinMain;
  qWinMain.setWindowTitle("Test Add Widget");
  QVBoxLayout qVBox;
  QPushButton qBtn("Add QLabel");
  qVBox.addWidget(&qBtn);
  qWinMain.setLayout(&qVBox);
  qWinMain.show();
  int i = 1;
  // install signal handlers
  QObject::connect(&qBtn, &QPushButton::clicked,
    [&](bool) {
      qVBox.addWidget(new QLabel(QString("QLabel %1").arg(i++)));
    });
  // runtime loop
  return app.exec();
}
CMakeLists.txt:

project(QWidgetAdd)

cmake_minimum_required(VERSION 3.10.0)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Qt5Widgets CONFIG REQUIRED)

include_directories("${CMAKE_SOURCE_DIR}")

add_executable(testQWidgetAdd testQWidgetAdd.cc)

target_link_libraries(testQWidgetAdd Qt5::Widgets)

输出:

c&#43;&#43; - 使用update()函数查看应用程序更改时出现问题-LMLPHP

并多次单击按钮“添加QLabel”后:

c&#43;&#43; - 使用update()函数查看应用程序更改时出现问题-LMLPHP

根据要求,OP提供了complete code on pastebin,我从中提取了以下代码段:
Base::Base(QWidget *parent)
    : QWidget(parent)
{
    QHBoxLayout* Hlayout=new QHBoxLayout(this);
    Vlayout=new QVBoxLayout(this);

    QPushButton *m=new QPushButton("exit",this);
    QPushButton *l=new QPushButton("+",this);

    Hlayout->addWidget(l);
    Hlayout->addWidget(m);

    Vlayout->addLayout(Hlayout);

    connect(l,SIGNAL(clicked()),this,SLOT(AddWidget()));
    connect(m,SIGNAL(clicked()),qApp,SLOT(quit()));

    m->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    l->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
}

这是具体的损坏部分:
    QHBoxLayout* Hlayout=new QHBoxLayout(this);
    Vlayout=new QVBoxLayout(this);

逐步说明:
  • class Base源自QWidget。因此,适用QWidget的布局管理。
  • QWidget支持一种布局来管理子代的位置和大小。
    它必须由QWidget::setLayout()应用。摘录自doc:

  • 可以使用或不使用父窗口小部件来构建布局。

  • 如果使用父窗口小部件(指向父窗口小部件)构造了布局,则将布局“隐式”设置为窗口小部件。否则,必须显式设置(使用QWidget::setLayout())或将其添加到其他布局。

    虽然,我个人更喜欢始终明确地设置布局(但这可能是个问题)。

    OP的实际错误:HlayoutVlayout是使用this构造的,但是this不能设置两个布局。因此,第二个被忽略。

    因此,添加到Vlayout的小部件将变得不可见,因为Vlayout中未设置this,并且QLabel不能成为this的子代。

    可能的解决方法:

    代替
        QHBoxLayout* Hlayout=new QHBoxLayout(this);
    

    它一定要是
        QHBoxLayout* Hlayout=new QHBoxLayout();
    

    Hlayout添加到Vlayout的行已经存在(但之前没有达到预期的效果):
        Vlayout->addLayout(Hlayout);
    

    关于c++ - 使用update()函数查看应用程序更改时出现问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61615812/

    10-11 22:23
    查看更多