Gtkmm - 改变Window的最小尺寸

时间:2015-08-13 13:52:44

标签: c++ gtk gtkmm gdk

我尝试更改Gtk :: Window的最小大小。应该可以将窗口缩小到更小的尺寸,然后将其中最大的容器缩小到特定尺寸。

我尝试了几种方法,你可以在下面看到。没有任何效果。最小值始终由图像大小定义。我做错了什么?

的main.cpp

#include "MainWindow.h"
#include <gtkmm.h>

int main (int argc, char* argv[])
{
  Glib::RefPtr<Gtk::Application> app =
    Gtk::Application::create(argc, argv, "org.gtkmm.example");

  MainWindow mainWindow;
  return app->run(mainWindow);
}

MainWindow.h

#ifndef MAINWINDOW_H_INCLUDED
#define MAINWINDOW_H_INCLUDED

#include <gtkmm.h>
#include <gdkmm.h>

class MainWindow : public Gtk::Window
{
  public:
    MainWindow();
  private:
    Gtk::Image   m_Image;
};

#endif // MAINWINDOW_H_INCLUDED

MainWindow.cpp

#include "MainWindow.h"

#define APPROACH_05

MainWindow::MainWindow() :
  m_Image( "image.png" )
{
  this->set_border_width(0);

#ifdef APPROACH_01
  this->add(m_Image);
  m_Image.set_size_request(5,5);
#endif // APPROACH_01

#ifdef APPROACH_02
  this->add(m_Image);
  this->set_size_request(5,5);
#endif // APPROACH_02

#ifdef APPROACH_03
  this->add(m_Image);
  Gtk::Allocation allocation = m_Image.get_allocation();
  allocation.set_width(5);
  allocation.set_height(5);
  m_Image.set_allocation(allocation);
#endif // APPROACH_03

#ifdef APPROACH_04
  this->add(m_Image);
  Gtk::Allocation allocation = this->get_allocation();
  allocation.set_width(5);
  allocation.set_height(5);
  this->set_allocation(allocation);
#endif // APPROACH_04

#ifdef APPROACH_05
  this->add(m_Image);
  Gdk::Geometry geom = {
    .min_width   = 5,
    .min_height  = 5,
  };
  Gtk::Window::set_geometry_hints(*this,geom,Gdk::HINT_MIN_SIZE);
#endif // APPROACH_05

  this->show_all_children();
}

编译:

g++ main.cpp MainWindow.cpp `pkg-config gtkmm-3.0 --cflags --libs` -o prog

@ptomato感谢您的回复。我试过这种方式:

#ifdef APPROACH_06
  this->add(m_ScrolledWindow);
  m_ScrolledWindow.set_border_width(0);
  m_ScrolledWindow.set_policy(Gtk::POLICY_NEVER,Gtk::POLICY_ALWAYS);
  m_ScrolledWindow.add(m_Image);
#endif // APPROACH_06

现在我可以垂直调整窗口大小,但是我看到了垂直滚动条。如果我将策略设置为POLICY_NEVER,就像在水平轴上一样,窗口宽度限制为图像宽度。此外,滑块的大小也限制了高度。

2 个答案:

答案 0 :(得分:1)

如果您希望能够将窗口缩小到比其中的图像更小的尺寸,则需要将图像放在Gtk::ScrolledWindow内,然后再将其添加到窗口中。如果不滚动,那么当您使窗口小于图像时,图像将无法知道要渲染的部分。

答案 1 :(得分:1)

有一种方法可以在窗口及其内容之间添加一个层,该层由一个自定义容器组成,该容器位于父窗口的首选大小。

这是我重写的GtkFixed,解决了完全相同的问题:

reckless_fixed.h

#ifndef __RECKLESS_FIXED_H__
#define __RECKLESS_FIXED_H__

#ifndef NO_INCLUDE_WITHIN_HEADERS
#include <gtk/gtk.h>
#endif

#define RECKLESS_FIXED_TYPE                  (reckless_fixed_get_type ())
#define RECKLESS_FIXED(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), RECKLESS_FIXED_TYPE, RecklessFixed))
#define RECKLESS_FIXED_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST  ((klass), RECKLESS_FIXED_TYPE, RecklessFixedClass))
#define IS_RECKLESS_FIXED(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RECKLESS_FIXED_TYPE))
#define IS_RECKLESS_FIXED_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE  ((klass), RECKLESS_FIXED_TYPE))
#define RECKLESS_FIXED_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS  ((obj), RECKLESS_FIXED_TYPE, RecklessFixedClass))

typedef struct _RecklessFixed      RecklessFixed;
typedef struct _RecklessFixedClass RecklessFixedClass;

struct _RecklessFixed
{
    GtkFixed container;
};

struct _RecklessFixedClass
{
    GtkFixedClass container_class;
};

GType reckless_fixed_get_type(void);
GtkWidget* reckless_fixed_new(void);

static void reckless_fixed_get_preferred_width(GtkWidget *widget, int *minimal, int *natural);
static void reckless_fixed_get_preferred_height(GtkWidget *widget, int *minimal, int *natural);

#endif /* __RECKLESS_FIXED_H__ */

reckless_fixed.c

#include <gtk/gtk.h>
#include "reckless_fixed.h"

G_DEFINE_TYPE( RecklessFixed, reckless_fixed, GTK_TYPE_FIXED )

static void reckless_fixed_class_init( RecklessFixedClass* klass ) {
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
    widget_class->get_preferred_width = reckless_fixed_get_preferred_width;
    widget_class->get_preferred_height = reckless_fixed_get_preferred_height;
}
static void reckless_fixed_init( RecklessFixed* self ) {}

// here is where we are reckless about our content's size
static void reckless_fixed_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
    *minimal = *natural = 1; 
}
//here too
static void reckless_fixed_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
    *minimal = *natural = 1;
}
GtkWidget* reckless_fixed_new (void) {
  return g_object_new (RECKLESS_FIXED_TYPE, NULL);
}

请注意GTK版本 - 以上示例适用于 GTK-3.0 。对于&lt; = 2.0, :: size-request 信号存在,通过连接和应答实现相同的目标。

除了我对这种方法提出警告之外 - 只有在您完全确定自己在做什么以及为什么需要与内容无关的窗口调整大小的情况下 ,因为这打破了内置的GTK布局系统。