为什么 GestureMultiPress 没有注册我的按键?

huangapple go评论62阅读模式
英文:

Why is this GestureMultiPress not registering my presses?

问题

我使用gtk-rs(GTK+ 3)制作了一个小应用程序,但无法注册鼠标点击事件。

我有一个DrawingArea,我希望每次在该DrawingArea中单击鼠标时运行一些代码。我理解可以使用GestureMultiPress 来实现这一点。(我知道事件也可以做到这一点,但我理解多重按手势也可以做到,而且我有印象它们(手势)更符合现代风格。)

这是我设置GestureMultiPress 代码的方式:

  let drw_area : DrawingArea  = ...;
  ...
  window.add(&drw_area);
  ...
  window.add_events(EventMask::BUTTON_PRESS_MASK | EventMask::BUTTON_RELEASE_MASK);
  let press =
    GestureMultiPress::builder()
      .button(0)
      .widget(&drw_area)
      .build();
  let _press_handler_id = {
    press.connect_pressed(|g, npress, x, y| {
      println!("({}, {npress}, {x}, {y})", g.current_button());
    })
  };

  ...

我期望这将在单击绘图区域时打印鼠标坐标,而在单击应用程序边框时不打印。但是,它根本不打印。

我在这里漏掉了什么/做错了什么?

完整的代码:

use gtk::gdk::EventMask;
use gtk::prelude::*;
use gtk::{DrawingArea, GestureMultiPress};

const APP_NAME : &'static str = "com.example.appname";
const APP_TITLE : &'static str = "Example App";

const APP_WIDTH : i32 = 600;
const APP_HEIGHT : i32 = 600;
const APP_BORDER_WIDTH : u32 = 20;

fn build_ui(application : &gtk::Application) {
  let window = gtk::ApplicationWindow::new(application);

  window.set_title(APP_TITLE);
  window.set_border_width(APP_BORDER_WIDTH);
  window.set_position(gtk::WindowPosition::Center);
  window.set_default_size(APP_WIDTH, APP_HEIGHT);

  let drw_area = {
    DrawingArea::builder()
      .width_request(APP_WIDTH - 2*APP_BORDER_WIDTH as i32)
      .height_request(APP_HEIGHT - 2*APP_BORDER_WIDTH as i32)
      .build()
  };

  drw_area.connect_draw(|a, c| {
    c.set_source_rgb(0.0, 0.0, 0.0);
    c.rectangle(0.0, 0.0, a.allocated_width() as f64, a.allocated_height() as f64);
    let _ = c.fill();
   Inhibit(false) 
  });
  window.add(&drw_area);

  window.add_events(EventMask::BUTTON_PRESS_MASK | EventMask::BUTTON_RELEASE_MASK);
  let press =
    GestureMultiPress::builder()
      .button(0)
      .widget(&drw_area)
      .build();
  let _press_handler_id = {
    press.connect_pressed(|g, npress, x, y| {
      println!("({}, {npress}, {x}, {y})", g.current_button());
    })
  };
 
  window.show_all();
}

fn main() {
  let application =
    gtk::Application::new(Some(APP_NAME), Default::default());
  application.connect_activate(build_ui);
  application.run();
}
英文:

I'm making a small app using gtk-rs (GTK+ 3), and I can't get it to register my mouse clicks.

I have a DrawingArea, and I want to run some code every time there's a mouse click in that DrawingArea. My understanding is that I can use a GestureMultiPress to do this. (I am aware events can also do this, but my understanding is that the multi-press gesture can do this too, and I had the impression that they (Gestures) are the more modern style.)

Here's how I set up the GestureMultiPress code:

  let drw_area : DrawingArea  = ...;
  ...
  window.add(&drw_area);
  ...
  window.add_events(EventMask::BUTTON_PRESS_MASK | EventMask::BUTTON_RELEASE_MASK);
  let press =
    GestureMultiPress::builder()
      .button(0)
      .widget(&drw_area)
      .build();
  let _press_handler_id = {
    press.connect_pressed(|g, npress, x, y| {
      println!("({}, {npress}, {x}, {y})", g.current_button());
    })
  };

  ...

I was expecting this to print the mouse coords when I clicked/released in the drawing area, and not print when I clicked/released in the app border. However, it's not printing at all.

What am I missing / doing wrong here?

Full Code:

use gtk::gdk::EventMask;
use gtk::prelude::*;
use gtk::{DrawingArea, GestureMultiPress};

const APP_NAME : &'static str = "com.example.appname";
const APP_TITLE : &'static str = "Example App";

const APP_WIDTH : i32 = 600;
const APP_HEIGHT : i32 = 600;
const APP_BORDER_WIDTH : u32 = 20;

fn build_ui(application : &gtk::Application) {
  let window = gtk::ApplicationWindow::new(application);

  window.set_title(APP_TITLE);
  window.set_border_width(APP_BORDER_WIDTH);
  window.set_position(gtk::WindowPosition::Center);
  window.set_default_size(APP_WIDTH, APP_HEIGHT);

  let drw_area = {
    DrawingArea::builder()
      .width_request(APP_WIDTH - 2*APP_BORDER_WIDTH as i32)
      .height_request(APP_HEIGHT - 2*APP_BORDER_WIDTH as i32)
      .build()
  };

  drw_area.connect_draw(|a, c| {
    c.set_source_rgb(0.0, 0.0, 0.0);
    c.rectangle(0.0, 0.0, a.allocated_width() as f64, a.allocated_height() as f64);
    let _ = c.fill();
   Inhibit(false) 
  });
  window.add(&drw_area);

  window.add_events(EventMask::BUTTON_PRESS_MASK | EventMask::BUTTON_RELEASE_MASK);
  let press =
    GestureMultiPress::builder()
      .button(0)
      .widget(&drw_area)
      .build();
  let _press_handler_id = {
    press.connect_pressed(|g, npress, x, y| {
      println!("({}, {npress}, {x}, {y})", g.current_button());
    })
  };
 
  window.show_all();
}

fn main() {
  let application =
    gtk::Application::new(Some(APP_NAME), Default::default());
  application.connect_activate(build_ui);
  application.run();
}

答案1

得分: 0

I have worked out the problem.

At the end of the scope, Rust deallocates the GestureMultiPress because it isn't referenced anywhere.

You can tell this by leaking a reference to it so that Rust doesn't deallocate it at the end of the scope.

  let a = Rc::new(press);
  mem::forget(a.clone());

I'm not sure how to actually keep the gesture around properly, given it's allocated inside a function with a fixed signature, so I can't pass things out; but that's a different question.

英文:

I have worked out the problem.

At the end of the scope, Rust deallocates the GestureMultiPress because it isn't referenced anywhere.

You can tell this by leaking a reference to it so that Rust doesn't deallocate it at the end of the scope.

  let a = Rc::new(press);
  mem::forget(a.clone());

I'm not sure how to actually keep the gesture around properly, given it's allocated inside a function with a fixed signature, so I can't pass things out; but that's a different question.

huangapple
  • 本文由 发表于 2023年3月7日 20:15:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75661854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定