C++ Gtk+;:如何从Cairo上下文设置窗口的光标?

C++ Gtk+;:如何从Cairo上下文设置窗口的光标?,c++,gtk,gtkmm,cairo,gdk,C++,Gtk,Gtkmm,Cairo,Gdk,我已经编写了以下代码来从Cairo::Context设置Gtk::Window的光标。当我运行程序并将光标移动到窗口中时,光标会在顶部变为一条水平黑线,然后在底部变为一些无法定义的白色形状。我希望光标变成一个黑色的16×16正方形。为什么光标没有呈现我想要的形状 #include <gtkmm.h> const int size = 16, hotspot = 0; class Window : public Gtk::Window { public: void ch

我已经编写了以下代码来从
Cairo::Context
设置
Gtk::Window
的光标。当我运行程序并将光标移动到窗口中时,光标会在顶部变为一条水平黑线,然后在底部变为一些无法定义的白色形状。我希望光标变成一个黑色的16×16正方形。为什么光标没有呈现我想要的形状

#include <gtkmm.h>

const int size = 16, hotspot = 0;

class Window : public Gtk::Window
{
  public:
    void change_cursor()
    {
      Glib::RefPtr<Gdk::Drawable> pixmap = Gdk::Pixmap::create(
          Glib::RefPtr<Gdk::Drawable>(), size, size, get_window()->get_depth());
      pixmap->set_colormap(get_window()->get_colormap());
      Cairo::RefPtr<Cairo::Context> context = pixmap->create_cairo_context();
      context->set_source_rgba(0, 0, 0, 0);
      context->rectangle(0, 0, size, size);
      context->fill();
      Glib::RefPtr<Gdk::Pixbuf> pixbuf
          = Gdk::Pixbuf::create(pixmap, 0, 0, size, size);
      Gdk::Cursor cursor(get_window()->get_display(), pixbuf, hotspot, hotspot);
      window->set_cursor(cursor);
    }
};

int main(int argc, char* argv[])
{
  Gtk::Main app(argc, argv);
  Window window;
  window.show_all();
  window.change_cursor();
  Gtk::Main::run(window);
  return 0;
}
#包括
常量int size=16,热点=0;
类窗口:公共Gtk::窗口
{
公众:
无效更改光标()
{
Glib::RefPtr pixmap=Gdk::pixmap::create(
Glib::RefPtr(),size,size,get_window()->get_depth();
pixmap->set_colormap(get_window()->get_colormap());
Cairo::RefPtr context=pixmap->create_Cairo_context();
context->set_source_rgba(0,0,0,0);
上下文->矩形(0,0,大小,大小);
上下文->填充();
Glib::RefPtr pixbuf
=Gdk::Pixbuf::create(pixmap,0,0,size,size);
Gdk::光标光标(get_window()->get_display(),pixbuf,热点,热点);
窗口->设置光标(光标);
}
};
int main(int argc,char*argv[])
{
Gtk::主应用程序(argc、argv);
窗口窗口;
window.show_all();
window.change_cursor();
Gtk::Main::run(窗口);
返回0;
}

当我将
Gdk::Pixmap
绘制到屏幕上时,它看起来很好。当我将
Gdk::Pixbuf
绘制到屏幕上时,我得到了垃圾。

我没有找出问题的原因,但找到了解决问题的方法:

  • 创建一个空的
    Gdk::Pixbuf
  • 使用
    Gdk::Pixbuf
    的像素作为数据缓冲区,创建一个
    Cairo::ImageSurface
  • Cairo::ImageSurface
    创建
    Cairo::Context
  • 清除
    Cairo::Context
    (这很重要,因为
    Gdk::Pixbuf
    的像素数据似乎尚未初始化)
  • 代码如下所示:

    Glib::RefPtr<Gdk::Pixbuf> pixbuf
        = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, size, size);
    Cairo::RefPtr<Cairo::ImageSurface> surface
        = Cairo::ImageSurface::create(
              pixbuf->get_pixels(), Cairo::FORMAT_ARGB32,
              size, size, pixbuf->get_rowstride() );
    Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface);
    context->save();
    context->set_operator(Cairo::OPERATOR_CLEAR);
    context->paint();
    context->restore();
    
      void fix_buffer_after_cairo(Glib::RefPtr<Gdk::Pixbuf> pixbuf)
      {
        guint8* pixels = pixbuf->get_pixels();
        int height = pixbuf->get_height();
        int width = pixbuf->get_width();
        int rowstride = pixbuf->get_rowstride();
    
        guint8 tmp;
        guint8* p;
        guint8* end;
    
        for (int j = height; j > 0; --j)
        {
          p = pixels;
          end = p + 4 * width;
          while (p < end)
          {
            tmp = p[0];
            if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
            {
              p[0] = p[2]; p[2] = tmp;
            }
            else
            {
              p[0] = p[1]; p[1] = p[2]; p[2] = p[3]; p[3] = tmp;
            }
            p += 4;
          }
          pixels += rowstride;
        }
      }
    }