内容缩小时动态缩小 GTK+ 中的窗口?
Posted
技术标签:
【中文标题】内容缩小时动态缩小 GTK+ 中的窗口?【英文标题】:Shrink window in GTK+ dynamically when content shrinks? 【发布时间】:2012-02-12 18:13:42 【问题描述】:我在 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。
那么任何想法如何调整窗口大小? 谢谢!
【问题讨论】:
这是一个真正的问题。我经常遇到这种情况(例如,从Gtk::ListBox
中删除的项目会使窗口变大)。
【参考方案1】:
如果我没记错的话,只有在元素太大而无法绘制时才会自动调整窗口大小。此外,set_default_size 方法仅在第一次绘制窗口时才重要,除非我错了,否则永远不会再次使用。我建议使用 resize 方法来设置窗口大小。 (link)
window.resize(box.width_request, box.height_request);
使用 resize 时需要记住的一件事是,如果您遇到该问题时无法将其调整为小于 request_size,请使用 set_request_size 方法。
【讨论】:
这里有几个拼写错误:实际的方法名称/签名(在绑定之间应该是等效的)是get_size_request(out width, out height)
和set_size_request(width, height)
。此外,get_size_request
仅对先前已明确设置请求的维度有意义;否则他们是-1。如果没有发出明确的请求,但用户仍然希望小部件具有适当的大小,则他们应该改用get_preferred_height/_width/_size
。然后,这将允许将窗口大小调整为小于首选尺寸(例如,如果它是可滚动的,则很有用)
链接已损坏。【参考方案2】:
我自己已经解决了这个问题,虽然接受的答案是正确的,但我可以给出一个更“完整”的答案,并带有工作代码。
重现问题
以下代码(在 C++ 中,抱歉)重现了您的问题:
#include <array>
#include <gtkmm.h>
class ResizableWindow : public Gtk::Window
public:
ResizableWindow()
: m_toggle"Toggle"
, m_currentImageIndex0
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 将根据几何约束自动调整窗口大小。
【讨论】:
以上是关于内容缩小时动态缩小 GTK+ 中的窗口?的主要内容,如果未能解决你的问题,请参考以下文章