gpt4 book ai didi

c++ - Gtk+ : How to set the cursor of a window from a Cairo context?

转载 作者:太空狗 更新时间:2023-10-29 21:29:25 24 4
gpt4 key购买 nike

我编写了以下代码来从 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;
}

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

最佳答案

我没有弄清楚问题的原因,但有一种解决方法:

  1. 创建一个空的Gdk::Pixbuf
  2. 使用 Gdk::Pixbuf 的像素作为数据缓冲区创建一个 Cairo::ImageSurface
  3. Cairo::ImageSurface 创建一个 Cairo::Context
  4. 清除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();

当我现在绘制到该上下文并从 Gdk::Pixbuf 设置光标时,我几乎得到了我想要的:形状很好,但是红色和蓝色被交换。这可以按照 Question 4291994 (How to write contents of a Cairo Image surface into a Gdk Pixbuf?) 中的概述进行修复:

  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;
}
}
}

关于c++ - Gtk+ : How to set the cursor of a window from a Cairo context?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4919264/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com