连接到实现信号:奇怪的窗口大小调整行为
Posted
技术标签:
【中文标题】连接到实现信号:奇怪的窗口大小调整行为【英文标题】:Connecting to the realize signal: strange window sizing behavior 【发布时间】:2020-04-10 14:06:07 【问题描述】:我正在使用 Gtkmm3 (Ubuntu) 制作一个小型 GUI 应用程序。在这个应用程序中,我有几个窗口要创建,它们基本上都遵循相同的模式:
-
注册主布局 (
Gtk::Grid
);
配置窗口属性(图标、标题等);
配置布局属性(扩展、子布局等);
配置窗口小部件(将它们添加到布局、标签等)。
希望每次创建新窗口时不必重写所有这些逻辑,我编写了以下基类:
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_appp_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
。这个策略的问题是,当我运行代码时,我得到了奇怪的窗口/布局大小:
请注意,黄色布局比其中包含的唯一小部件(按钮)大得多。这是我所期望的结果:
也就是说,窗口和主布局应该缩小到它们唯一包含的小部件的大小。奇怪的是,如果我将窗口设为set_resizable(false)
,我会得到我想要的大小,但是我不能再调整它的大小,这通常是不可接受的。
问题:
-
为什么不是这样(为什么布局占用了这么多额外空间)?
如何在不为每个窗口复制基本代码的情况下实现这一点?
您可以使用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`
【问题讨论】:
【参考方案1】:这是网格的默认行为。您可以尝试一个简单的示例,其中包含一个窗口、一个网格和一个按钮。网格内的元素不会自动扩展以占用分配的网格大小。为此,您需要添加
button.set_hexpand(true);
button.set_vexpand(true);
这是关于网格与框的一个很好的参考。 https://people.gnome.org/~ryanl/gtk/html/ch28s02.html
【讨论】:
我知道,我已经尝试过了,它给了我第二个输出(布局的大小等于按钮的大小)。我在问为什么布局在窗口中占用这么多空间而不是调整按钮的大小,就像您所指的简单示例中那样。感谢您的参考。 感谢您的意见,我澄清了这个问题。以上是关于连接到实现信号:奇怪的窗口大小调整行为的主要内容,如果未能解决你的问题,请参考以下文章