如何在窗口小部件上禁用最小尺寸设置以绘制窗口背景图像

时间:2015-08-11 22:17:31

标签: c++ gtk gtk3 gtkmm

我是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

res/background.png

启动后窗口的快照

snapshot of the window after start

调整大小后

窗口的快照

snapshot of the window after resizing

问题

如您所见,您可以放大窗口,背景适合其大小。但你不能减小尺寸。我该怎么做才能调整大小到前景的大小?

我搜索get_preferred_width的相反方法,因为我认为此调整会限制调整大小。

我的方法

我尝试了set_size_requestset_geometry_hints,但没有任何效果。

0 个答案:

没有答案