我在Vala应用程序中有一个窗口,里面有一个图像.这个图像有时会被更改img.set_from_pixbuf(imgdata);,因此它的大小也会发生变化.它嵌入在Gtk.Box中.
box = new Gtk.Box(Orientation.VERTICAL,5);
...
box.pack_end(img,false,false);
因此,如果以前有一个大图像,我用一个较小的图像替换它,窗口仍然是非常大的,我没有找到一种方法动态缩小到所需的空间.我试过window.set_default_size(box.width_request,box.height_request)但它总是返回-1.
那么任何想法如何调整窗口大小?谢谢!
我自己也曾与这个问题作过斗争,虽然接受的答案是正确的,但我想我可以用工作代码给出一个更“完整”的答案。
以下代码(在 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按钮更改底层图像。两者是相同的图像,但大小不同。请注意,正如您已经提到的,第一次切换时(小 -> 大),窗口会适当调整大小。但是,当第二次切换时(大 --> 小),图像的大小会调整,但窗口的大小不会调整,从而在图像周围留下额外的空间:
奇怪,我知道...
要解决这个问题,需要调用该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 将根据几何约束自动调整窗口大小。
如果我没有弄错的话,窗口的自动调整大小只会发生在元素太大而无法绘制时。另外, set_default_size 方法仅在第一次绘制窗口时才重要,除非我错了,否则永远不会再次使用。我建议使用调整大小方法来设置窗口大小。(关联)
window.resize(box.width_request, box.height_request);
使用调整大小时需要记住的一件事是,如果您无法将其调整为小于 request_size,如果您遇到该问题,请使用 set_request_size 方法。