更新DrawingArea的绘图功能 [英] Update drawing function of a DrawingArea

查看:95
本文介绍了更新DrawingArea的绘图功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想更新DrawingArea中的开罗图形.我试图通过使用新函数作为参数调用 DrawingArea :: connect_draw(...)来实现此目的.我的问题是,它不能代替原始绘图功能,但在显示窗口时会同时调用两者.这是一个例子

I want to update a cairo drawing inside a DrawingArea. I tried to achieve this by calling DrawingArea::connect_draw(...) with a new function as the parameter. My issue is that it does not replace the original drawing function, but calls both when showing the window. Here is an example

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

use gio::prelude::*;
use gtk::prelude::*;

fn main() {
    let application = gtk::Application::new(Some("com.example"), Default::default())
        .expect("Initialization failed...");

    application.connect_activate(|app| {
        build_ui(app);
    });

    application.run(&vec![]);
}

fn build_ui(application: &gtk::Application) {
    let window = get_window(application);
    let drawing_area = Box::new(gtk::DrawingArea::new)();

    // Set drawing function
    drawing_area.connect_draw(|_, ctx| draw(ctx, 0.5, 2.0));
    // Change drawing function
    drawing_area.connect_draw(|_, ctx| draw(ctx, 0.9, 1.0)); // <-- Why is this not working as expected?

    window.add(&drawing_area);
    window.show_all();
}

fn get_window(application: &gtk::Application) -> gtk::ApplicationWindow {
    let window = gtk::ApplicationWindow::new(application);
    window.set_default_size(500i32, 500i32);

    // Set transparency
    set_visual(&window, None);
    window.connect_screen_changed(set_visual);
    window.set_app_paintable(true);

    window
}

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

    ctx.set_source_rgba(1.0, 0.2, 0.2, param1);
    ctx.arc(0.5, 0.5, 0.2, 0.0, 3.1414 * param2);
    ctx.fill();

    Inhibit(false)
}

fn set_visual(window: &gtk::ApplicationWindow, _screen: Option<&gdk::Screen>) {
    if let Some(screen) = window.get_screen() {
        if let Some(ref visual) = screen.get_rgba_visual() {
            window.set_visual(Some(visual));
        }
    }
}

我希望显示半个圆圈.尽管我试图替换connect_draw,但旧的,完整的圆圈仍然存在.我该如何正确更换呢?

I expect half a circle to be shown. Yet the old, full circle is still there, even though I tried to replace connect_draw. How can I properly replace this?

推荐答案

使用 connect_draw 函数将附加另一个信号处理程序,但不会替换现有的处理程序.但是,该函数返回一个 SignalHandlerId ,然后您便可以使用 signal_handler_disconnect 函数将其用于断开原始信号处理程序的连接(请参阅

Using the connect_draw function attaches another signal handler, but will not replace existing handlers. However, the function returns a SignalHandlerId which you should then be able to use to disonnect your original signal handler using the signal_handler_disconnect function (see https://gtk-rs.org/docs/glib/signal/fn.signal_handler_disconnect.html).

这篇关于更新DrawingArea的绘图功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆