0

我只想在绘图区域内显示开罗绘图,但由于某种原因,绘图周围总是有一个彩色矩形背景。我怎样才能摆脱这个?我特别不想将它设置为透明(因为我可能不支持透明度),而是只显示绘图本身。

我的例子是在 Rust 中使用 gtk-rs,但其他语言的任何提示也很棒!

extern crate cairo;
extern crate gio;
extern crate gtk;

use gtk::prelude::*;

fn main() {
    gtk::init();
    show_drawing();
    gtk::main();
}

fn show_drawing() {
    let window = gtk::Window::new(gtk::WindowType::Popup);
    window.set_default_size(500i32, 500i32);

    // Make window a Notification
    window.set_type_hint(gdk::WindowTypeHint::Notification);
    window.set_position(gtk::WindowPosition::Center);

    // Add drawing
    let drawing_area = Box::new(gtk::DrawingArea::new)();
    drawing_area.connect_draw(move |_, ctx| draw(ctx));
    window.add(&drawing_area);

    window.show_all();
}

fn draw(ctx: &cairo::Context) -> gtk::Inhibit {
    ctx.scale(500f64, 500f64);

    ctx.set_source_rgba(1.0, 0.2, 0.2, 1.0);
    ctx.arc(0.5, 0.5, 0.5, 0., 3.1414 * 2.);
    ctx.fill();

    Inhibit(false)
}

我希望它只显示圆圈,并在圆圈周围查看并保持浏览器可点击。我怎么能做到这一点?

在此处输入图像描述

4

1 回答 1

2

你可以试试这个:

#include <gtk/gtk.h>

GtkWidget *window;
GtkWidget *drawing_area;

gboolean
on_draw (GtkWidget *widget,
         cairo_t *cr,
         gpointer user_data)
{
  guint width, height;
  GdkRGBA color;
  GtkStyleContext *context;

  context = gtk_widget_get_style_context (widget);

  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  gtk_render_background (context, cr, 0, 0, width, height);

  cairo_arc (cr,
             width / 2.0, height / 2.0,
             MIN (width, height) / 2.0,
             0, 2 * G_PI);

  gtk_style_context_get_color (context,
                               gtk_style_context_get_state (context),
                               &color);
  gdk_cairo_set_source_rgba (cr, &color);

  cairo_fill (cr);

  return FALSE;
}

gboolean on_window_button_press (GtkWidget *window,
                                 GdkEvent *event,
                                 gpointer user)
{
  GdkEventButton *e = (GdkEventButton*) event;

  if (e->type == GDK_BUTTON_PRESS && e->button == 1) {
    gtk_window_begin_move_drag (GTK_WINDOW(window),
                                e->button,
                                e->x_root,
                                e->y_root,
                                e->time);
    return TRUE;
  }
  return FALSE;
}

int
main (int argc, char **argv) {
  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  drawing_area = gtk_drawing_area_new ();

  gtk_widget_set_size_request (drawing_area, 300, 300);
  gtk_container_add (GTK_CONTAINER(window), drawing_area);

  g_signal_connect (drawing_area, "draw", G_CALLBACK (on_draw), NULL);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);

  /*we want no window decorations*/
  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
  /*enable use of the alpha channel on window*/
  GdkScreen *screen = gtk_widget_get_screen (window);
  GdkVisual *rgba_visual = gdk_screen_get_rgba_visual (screen);
  gtk_widget_set_visual (window, rgba_visual);
  /*now set a transparent background*/
  GtkCssProvider *css = gtk_css_provider_new ();
  gtk_css_provider_load_from_data (css, "window { background-color: transparent; }", -1, NULL);
  gtk_style_context_add_provider (gtk_widget_get_style_context (window),
                                  GTK_STYLE_PROVIDER (css),
                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
  /*or, alternatively, you can set app-paintable to skip drawing the background*/
  /*gtk_widget_set_app_paintable (window, TRUE);*/
  /*drag window around by left click*/
  gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK);
  g_signal_connect (window,
                    "button-press-event",
                    G_CALLBACK (on_window_button_press),
                    NULL);

  gtk_widget_show_all (window);
  gtk_main();

  return 0;
}

注意:在 X11 上,这仅适用于合成窗口管理器。另一种方法是使用gdk_window_shape_combine_region(或类似函数之一)设置窗口形状。相反,它使用广泛可用的 XShape 扩展。

希望能帮助到你!:)

于 2019-11-01T21:54:05.437 回答