Gtkmm — изменить минимальный размер окна

Я пытаюсь изменить минимальный размер 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 как и на горизонтальной оси, ширина окна ограничена шириной изображения. Кроме того, размер слайдера также ограничивает высоту.

0

Решение

Если вы хотите иметь возможность уменьшить окно до меньшего размера, чем изображение внутри него, то вам нужно поместить изображение внутри Gtk::ScrolledWindow прежде чем добавить его в окно. Без прокрутки изображение не будет знать, какую часть изображения визуализировать, когда вы сделаете окно меньше, чем изображение.

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. За <= 2,0 :: размерно-запрос Сигнал существует, подключаясь и отвечая на который достигается та же цель.

Кроме того, я бы предупредил об этом подходе — сделай это только в тех случаях, когда вы абсолютно уверены в том, что делаете, и зачем вам нужно изменять размер окна, не зависящего от содержимого, так как это нарушает встроенную систему разметки GTK.

1

По вопросам рекламы [email protected]