我是Gtkmm3的新手,我尝试了几件事。目前,我使用背景图像编写了一个窗口类。我搜索了很多,但我没有找到任何有用/有用的Gtkmm3示例。最后,应该可以调整窗口大小,并且背景通过构建相同图像的图案并将其切割成所需大小(而不是通过缩放图像)来调整自身大小。
所以我将一个基本网格(Gtk :: Grid)添加到主窗口(Gtk :: Image),加载图像,将它们放入背景网格(Gtk :: Grid)并将其附加到基础网格中与前景网格(Gtk :: Grid)相同的位置。 一种方法有助于调整背景大小。
代码如下:
生成文件
SRC = main.cpp
SRC += ./src/MainWindow.cpp
TARGET = prog
CC = g++
LIBS = `pkg-config gtkmm-3.0 --cflags --libs`
all:
$(CC) $(SRC) $(LIBS) -o $(TARGET)
的main.cpp
#include "./inc/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;
//Shows the mainWindow and returns when it is closed.
return app->run(mainWindow);
}
INC / MainWindow.h
#ifndef MAINWINDOW_H_INCLUDED
#define MAINWINDOW_H_INCLUDED
#include <gtkmm.h>
#include <gdkmm.h>
class MainWindow :
public Gtk::Window
{
public:
/** Default constructor */
MainWindow();
/** Default destructor */
virtual ~MainWindow();
protected:
private:
// signal handlers
void on_ButtonQuit_clicked ( void );
void on_MainWindow_check_resize();
// methods
void resizeBackground(int width, int height);
// member data
Gtk::Grid m_GridBase;
Gtk::Grid m_ForegroundGrid;
Gtk::Label m_Label1;
Gtk::ButtonBox m_ButtonBox;
Gtk::Button m_ButtonQuit;
Gtk::Image m_BackgroundImage;
Glib::RefPtr<Gdk::Pixbuf> m_BackgroundImagePixbuf;
int m_BackgroundImageWidth;
int m_BackgroundImageHeight;
bool m_resizeBackgroundStatus;
};
#endif // MAINWINDOW_H_INCLUDED
的src / MainWindow.cpp
#include "../inc/MainWindow.h"
MainWindow::MainWindow() :
m_ButtonBox(),
m_ButtonQuit( Gtk::Stock::QUIT ),
m_BackgroundImage( "res/background.png" ),
m_ForegroundGrid(),
m_GridBase(),
m_Label1 ( "Beispiel Label",
/*xalign*/ Gtk::ALIGN_CENTER,
/*yalign*/ Gtk::ALIGN_CENTER,
/*mnemonic*/ false)
{
// setting up the window
this->set_title( "Window with backround" );
this->set_border_width(0);
// hide titlebar
//this->set_decorated(false);
m_BackgroundImagePixbuf = m_BackgroundImage.get_pixbuf();
m_BackgroundImageWidth = m_BackgroundImagePixbuf->get_width();
m_BackgroundImageHeight = m_BackgroundImagePixbuf->get_height();
// ad the base grid to the window
this->add(m_GridBase);
// attach the foreground grid and the background image to the base grid
m_GridBase.attach(m_ForegroundGrid,1,1,1,1);
// at least (!) attach the background picture
m_GridBase.attach(m_BackgroundImage,1,1,1,1);
// pack the foreground grid
m_ForegroundGrid.attach(m_ButtonBox,2,2,1,1);
m_ForegroundGrid.attach(m_Label1,1,1,1,1);
m_ButtonBox.pack_start(m_ButtonQuit, Gtk::PACK_SHRINK);
// get the dimension of packed foreground grid for resizing the background
m_ForegroundGrid.show_all();
int min_width; int nat_width; int min_height; int nat_height;
m_ForegroundGrid.get_preferred_width(min_width,nat_width);
m_ForegroundGrid.get_preferred_height(min_height,nat_height);
this->resizeBackground(min_width, min_height);
// initialize the status flag for on_MainWindow_check_resize
m_resizeBackgroundStatus = true;
// connect signals
m_ButtonQuit.signal_clicked().connect(
sigc::mem_fun(*this, &MainWindow::on_ButtonQuit_clicked));
this->signal_check_resize().connect(
sigc::mem_fun(*this, &MainWindow::on_MainWindow_check_resize));
this->show_all_children();
}
MainWindow::~MainWindow()
{
//dtor
}
void MainWindow::on_ButtonQuit_clicked(void)
{
this->hide();
}
void MainWindow::on_MainWindow_check_resize()
{
// check status to prevent recursive callings
if(m_resizeBackgroundStatus==true)
{
Gtk::Allocation allocation = this->get_allocation();
const int width = allocation.get_width();
const int height = allocation.get_height();
m_resizeBackgroundStatus = false;
this->resizeBackground(width, height);
}
else
{
m_resizeBackgroundStatus = true;
}
}
void MainWindow::resizeBackground(int width, int height)
{
Glib::RefPtr<Gdk::Pixbuf> BackgroundPixbuf =
Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,true,8,width,height);
int xcnt = width/m_BackgroundImageWidth + 1;
int ycnt = height/m_BackgroundImageHeight + 1;
Glib::RefPtr<Gdk::Pixbuf> BackgroundTmpPixbuf =
Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,true,8,
xcnt*m_BackgroundImageWidth,
ycnt*m_BackgroundImageHeight);
for( xcnt = width/m_BackgroundImageWidth; xcnt>=0; xcnt--)
{
for( ycnt = height/m_BackgroundImageHeight; ycnt>=0; ycnt--)
{
m_BackgroundImagePixbuf->scale(
BackgroundTmpPixbuf, // destination Pixbuf
xcnt*m_BackgroundImageWidth, // dest_x
ycnt*m_BackgroundImageHeight, // dest_y
m_BackgroundImageWidth, // dest_width
m_BackgroundImageHeight, // dest_height
xcnt*m_BackgroundImageWidth, // offset_x = dest_x
ycnt*m_BackgroundImageHeight, // offset_y = dest_y
1, // scale_x
1, // scale_y
Gdk::INTERP_NEAREST //interp_type
);
}
}
BackgroundTmpPixbuf->scale(
BackgroundPixbuf, // destination Pixbuf
0, // dest_x
0, // dest_y
width, // dest_width
height, // dest_height
0, // offset_x = dest_x
0, // offset_y = dest_y
1, // scale_x
1, // scale_y
Gdk::INTERP_NEAREST //interp_type
);
m_BackgroundImage.set(BackgroundPixbuf);
// int min_width; int nat_width; int min_height; int nat_height;
// m_Grid.get_preferred_width(min_width,nat_width);
// m_Grid.get_preferred_height(min_height,nat_height);
// printf("%d\n",min_width);
// m_GridBase.set_size_request(min_width,min_height);
// this->set_size_request(min_width,min_height);
// m_BackgroundImage.set_size_request(min_width,min_height);
// const Gdk::Geometry geometry = 0;
// this->set_geometry_hints(geometry,0);
}
RES / background.png
启动后窗口的快照
调整大小后窗口的快照
问题
如您所见,您可以放大窗口,背景适合其大小。但你不能减小尺寸。我该怎么做才能调整大小到前景的大小?
我搜索get_preferred_width
的相反方法,因为我认为此调整会限制调整大小。
我的方法
我尝试了set_size_request
或set_geometry_hints
,但没有任何效果。