Gtk::Window 添加网格未显示我的子部件

Gtk::Window add grid is not showing my child widgets

我将两个小部件附加到一个网格;一个标签和一个旋转按钮,然后将网格添加到 Gtk::Window

我得到这样的空白输出:

#include <gtkmm.h>

class SpinButtonExample : public Gtk::Window {
public:
    SpinButtonExample();
};

SpinButtonExample::SpinButtonExample()
{
    auto grid       = Gtk::Grid();
    auto label      = Gtk::Label("Hi!");
    auto adjustment = Gtk::Adjustment::create(0, 0, 10);
    auto spinbutton = Gtk::SpinButton(adjustment);

    grid.set_column_homogeneous(true);
    grid.attach(label     , 0, 0, 1, 1);
    grid.attach(spinbutton, 1, 0, 1, 1);

    add(grid);

    show_all();
}

int main()
{
    auto application = Gtk::Application::create("test.focus.spinbutton");

    SpinButtonExample test;

    return application->run(test);
}

但是,如果我使用 glade 文件,它工作正常,但我想用代码来做,但我被卡住了...

由于您的 grid 变量(以及所有其他变量)是局部变量,它们会在 SpinButtonExample::SpinButtonExample() 完成后被销毁。

这不是 GTK 特有的,这是一个 C++ 内存管理问题。局部变量在其范围结束时被销毁。

您需要一种方法来在构造函数完成后保留对小部件的引用。最简单的方法是将 grid 声明为 class 成员。这样,只要包含 class 存在,它就会存在。

您还可以使用 new 为对象动态分配内存,但是您需要 delete 指针以避免内存泄漏。无论如何你都需要存储指针。

对于子窗口小部件,您可以动态分配它们,并在使用 Gtk::make_managed 销毁其父对象时销毁它们。我在下面的示例中使用 spinbutton 来展示基本思想。

哪种方式最好,要视情况而定。

这是您的代码的更新版本,显示了一些保留对小部件的引用的方法:

#include <gtkmm.h>

class SpinButtonExample : public Gtk::Window {
public:
    SpinButtonExample();

private:
    Gtk::Grid grid;
    Gtk::Label label;
};

SpinButtonExample::SpinButtonExample()
  : grid()
  , label("Hi!")
{
    auto adjustment = Gtk::Adjustment::create(0, 0, 10);
    auto spinbutton = Gtk::make_managed<Gtk::SpinButton>(adjustment);

    grid.set_column_homogeneous(true);
    grid.attach(label      , 0, 0, 1, 1);
    grid.attach(*spinbutton, 1, 0, 1, 1);

    add(grid);

    show_all();
}

int main()
{
    auto application = Gtk::Application::create("test.focus.spinbutton");

    SpinButtonExample test;

    return application->run(test);
}

另见 https://developer.gnome.org/gtkmm-tutorial/stable/sec-memory-widgets.html.en