私は自分でこの問題と戦ってきましたが、受け入れられた答えは正しいですが、動作するコードを使用して、より「完全な」答えを出すことができました。
問題の再現
次のコード (C++ の場合、申し訳ありません) で問題が再現されます。
#include <array>
#include <gtkmm.h>
class ResizableWindow : public Gtk::Window
{
public:
ResizableWindow()
: m_toggle{"Toggle"}
, m_currentImageIndex{0}
{
m_files[0] = "small.png";
m_files[1] = "large.png";
// Setup window layout:
m_layout.attach(*Gtk::manage(new Gtk::Image(m_files[m_currentImageIndex])), 0, 0, 1, 1);
m_layout.attach(m_toggle, 0, 1, 1, 1);
add(m_layout);
// Set up signal handlers:
m_toggle.signal_clicked().connect([this](){OnToggle();});
}
private:
void OnToggle()
{
// Switch image file:
if(m_currentImageIndex == 0)
{
m_currentImageIndex = 1;
}
else
{
m_currentImageIndex = 0;
}
// Load new image.
Gtk::Widget* child = m_layout.get_child_at(0, 0);
Gtk::Image* currentImage = dynamic_cast<Gtk::Image*>(child);
currentImage->set(m_files[m_currentImageIndex]);
}
Gtk::Grid m_layout;
Gtk::Button m_toggle;
std::array<std::string, 2> m_files;
size_t m_currentImageIndex;
};
int main (int argc, char* argv[])
{
auto app = Gtk::Application::create(argc, argv, "so.question.q8903140");
ResizableWindow w;
w.show_all();
return app->run(w);
}
Toggle
ボタンは下にある画像を変更します。どちらも同じ画像ですが、サイズが異なります。すでに述べたように、初めてトグルするとき (小 --> 大)、ウィンドウのサイズが適切に変更されることに注意してください。ただし、2 回目のトグル (大 --> 小) を行うと、画像のサイズが変更されますが、ウィンドウは変更されず、画像の周りに余分なスペースが残ります。

奇妙な、私は知っている...
解決
resize
この問題を解決するには、メソッドを呼び出す必要があります。したがって、Toggle
ハンドラーは次のようになります。
void OnToggle()
{
if(m_currentImageIndex == 0)
{
m_currentImageIndex = 1;
}
else
{
m_currentImageIndex = 0;
}
Gtk::Widget* child = m_layout.get_child_at(0, 0);
Gtk::Image* currentImage = dynamic_cast<Gtk::Image*>(child);
currentImage->set(m_files[m_currentImageIndex]);
// Resize window:
resize(1, 1);
}
resize
が 1x1 の次元 (可能な限り小さい次元) で呼び出されたことに注意してください。Gtkmm は、そこから自動的にジオメトリ制約に従ってウィンドウのサイズを変更します。