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