连接到实现信号:奇怪的窗口大小调整行为

问题描述 投票:0回答:1

我正在使用Gtkmm3(Ubuntu)制作一个小型GUI应用程序。在此应用程序中,我要创建几个窗口,基本上所有窗口都遵循相同的模式:

  1. 注册主布局(Gtk::Grid);
  2. 配置窗口属性(图标,标题等);
  3. 配置布局属性(展开,子布局等);
  4. 配置窗口小部件(将它们添加到布局,标签等)。

为了避免每次创建新窗口时都不必重写所有这些逻辑,我编写了以下基类:

template<typename GtkmmWindow>
class Window
{

public:

    Window();

    virtual int Show() = 0;


protected:

    virtual void ConfigureWindow() = 0;
    virtual void ConfigureLayouts() = 0;
    virtual void ConfigureWidgets() = 0;

    void Init();


    Gtk::Grid m_mainLayout;
    GtkmmWindow m_window;

};

template<typename GtkmmWindow>
Window<GtkmmWindow>::Window()
{
    m_window.add(m_mainLayout);

    // When signal 'realize' is sent, 'Init' will be triggered.
    // This happens after construction, so virtual methods can
    // be used safely:
    m_window.signal_realize().connect([this](){Init();});
}

// Initialize child window according to its own needs:
template<typename GtkmmWindow>
void Window<GtkmmWindow>::Init()
{
    ConfigureWindow();
    ConfigureLayouts();
    ConfigureWidgets();

    // If this line is removed, no widgets are shown.
    m_window.show_all_children();
}

此类的目标是确保所有窗口以相同的方式实现点1至4。它通过在发送realize信号时调用适当的虚方法(将在具体的子类中重新定义)来实现。这是因为当发送realize信号时,我知道已经调用了窗口构造函数,并且可以安全地使用虚拟方法。

例如,这是我使用它创建应用程序主窗口的方式:

class MyWindow : public Window<Gtk::ApplicationWindow>
{

public:

    MyWindow(Gtk::Application& p_app) : m_app{p_app} {}

    int Show() override
    {
        m_window.show_all();
        return m_app.run(m_window);
    }

private:

    Gtk::Application& m_app;
    Gtk::Button m_button;

    void ConfigureWindow() override
    {
        m_window.set_title("SO Question");

        // If I set this to false, the window shrinks to fit the button size:
        m_window.set_resizable(false);
    }

    void ConfigureLayouts() override
    {
        m_mainLayout.override_background_color(Gdk::RGBA("yellow"));
    }

    void ConfigureWidgets() override
    {
        m_mainLayout.attach(m_button, 0, 0, 1, 1);
        m_button.set_label("Hello");
    }

};

此主窗口将主布局设置为黄色背景,并在主布局中注册了带有标签“ Hello”的Gtk::Button。这种策略的问题在于,当我运行代码时,我得到了奇怪的窗口/布局大小:

enter image description here

注意,黄色布局比其中包含的唯一窗口小部件(按钮)大得多。这是我所期望的结果:

enter image description here

即,窗口和主布局应缩小到其唯一包含的窗口小部件的大小。奇怪的是,如果我将窗口设为set_resizable(false),则会得到所需的大小,但是我无法再调整其大小,这通常是不可接受的。

问题:

  1. 为什么不是这样(为什么布局会占用这么多额外的空间?]
  2. 如何在不复制每个窗口的基本代码的情况下实现这一目标?

您可以通过将g++添加到以下代码来构建此代码:

#include <memory>
#include <gtkmm.h>

// Add here...

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create(argc, argv, "so.realize");

  std::unique_ptr<MyWindow> mainWindow = std::make_unique<MyWindow>(*(app.get()));

  return mainWindow->Show();
}

并且正在运行:

g++ -std=c++17 main.cpp -o example.out `pkg-config gtkmm-3.0 --cflags --libs`
c++ gtk gtk3 gtkmm gtkmm3
1个回答
0
投票

这是网格的默认行为。您可以尝试一个简单的示例,其中包含一个窗口,一个网格和一个按钮。网格内的元素不会自动扩展以占据分配的网格大小。为此,您需要添加

button.set_hexpand(true);
button.set_vexpand(true);

这里是关于网格与框的良好参考。 https://people.gnome.org/~ryanl/gtk/html/ch28s02.html

© www.soinside.com 2019 - 2024. All rights reserved.