在Gtk中如何能够监听全局鼠标键盘事件?

软件和网站开发以及相关技术探讨
回复
lcqtdwj
帖子: 8
注册时间: 2011-11-24 22:35

在Gtk中如何能够监听全局鼠标键盘事件?

#1

帖子 lcqtdwj » 2014-08-23 18:46

Hello,大家好。最近我在学习使用PyGObject,在一个Gtk.Widget中我能够用监听"motion-notify-event"获得鼠标移动事件。但是只有鼠标在窗口中才行,我想要窗口外的鼠标事件应该怎么办?
我想到用timeout去做,但是应该不是最佳的方法。我想有什么我应该不知道,恳请指导
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#2

帖子 eexpress » 2014-08-23 22:25

你应该获取root窗口的id,然后
add_events (Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.SCROLL_MASK|Gdk.EventMask.ENTER_NOTIFY_MASK);

类似这样的添加事件。

或者监视丢失焦点的事件。
● 鸣学
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#3

帖子 astolia » 2014-08-24 0:12

对你想要监听的窗口设置事件掩码PointerMotionMask
window.set_events(window.get_events() | Gdk.EventMask.POINTER_MOTION_MASK)
如果需求符合的话也可以直接捕获鼠标
Gdk.pointer_grab

http://www.roojs.com/seed/gir-1.2-gtk-3 ... tMask.html
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#4

帖子 astolia » 2014-08-24 0:15

用python-xlib实现的简单例子,原理是一样的

代码: 全选

import Xlib.X
import Xlib.display
display = Xlib.display.Display()
root = display.screen().root
root.change_attributes(event_mask=Xlib.X.PointerMotionMask)
#root.grab_pointer(True, Xlib.X.PointerMotionMask, 1, 1, 0, 0, 0)
while True:
  if display.pending_events() > 0:
    event = display.next_event()
    if event.type == Xlib.X.MotionNotify:
      print event.root_x, event.root_y
lcqtdwj
帖子: 8
注册时间: 2011-11-24 22:35

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#5

帖子 lcqtdwj » 2014-08-24 11:33

我试了不行,只有鼠标在窗口内才有反应。。
astolia 写了:用python-xlib实现的简单例子,原理是一样的

代码: 全选

import Xlib.X
import Xlib.display
display = Xlib.display.Display()
root = display.screen().root
root.change_attributes(event_mask=Xlib.X.PointerMotionMask)
#root.grab_pointer(True, Xlib.X.PointerMotionMask, 1, 1, 0, 0, 0)
while True:
  if display.pending_events() > 0:
    event = display.next_event()
    if event.type == Xlib.X.MotionNotify:
      print event.root_x, event.root_y
lcqtdwj
帖子: 8
注册时间: 2011-11-24 22:35

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#6

帖子 lcqtdwj » 2014-08-24 11:37

用get_root_window()获得的是GdkX11Window,没有这些事件
eexpress 写了:你应该获取root窗口的id,然后
add_events (Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.SCROLL_MASK|Gdk.EventMask.ENTER_NOTIFY_MASK);

类似这样的添加事件。

或者监视丢失焦点的事件。
lcqtdwj
帖子: 8
注册时间: 2011-11-24 22:35

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#7

帖子 lcqtdwj » 2014-08-24 11:53

root.grab_pointer是可以获得,但是其他窗口就控制不了了。
astolia 写了:用python-xlib实现的简单例子,原理是一样的

代码: 全选

import Xlib.X
import Xlib.display
display = Xlib.display.Display()
root = display.screen().root
root.change_attributes(event_mask=Xlib.X.PointerMotionMask)
#root.grab_pointer(True, Xlib.X.PointerMotionMask, 1, 1, 0, 0, 0)
while True:
  if display.pending_events() > 0:
    event = display.next_event()
    if event.type == Xlib.X.MotionNotify:
      print event.root_x, event.root_y
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#8

帖子 astolia » 2014-08-30 22:23

lcqtdwj 写了:我试了不行,只有鼠标在窗口内才有反应。。
astolia 写了:用python-xlib实现的简单例子,原理是一样的

代码: 全选

import Xlib.X
import Xlib.display
display = Xlib.display.Display()
root = display.screen().root
root.change_attributes(event_mask=Xlib.X.PointerMotionMask)
#root.grab_pointer(True, Xlib.X.PointerMotionMask, 1, 1, 0, 0, 0)
while True:
  if display.pending_events() > 0:
    event = display.next_event()
    if event.type == Xlib.X.MotionNotify:
      print event.root_x, event.root_y
承认吧,你不知道根窗口是什么东西,也没有仔细读我3楼写的东西,我单独标注出来好了
你想要监听的窗口设置事件掩码PointerMotionMask
我的代码里只对根窗口设置了,所以只能额外接收到根窗口的事件。你不知道根窗口在哪里,所以也接收不到事件信息
你要监听所有窗口的,又不是想成为窗口管理器的话,只有搞遍历去设置了,性能不见得比定时查询高
lcqtdwj
帖子: 8
注册时间: 2011-11-24 22:35

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#9

帖子 lcqtdwj » 2014-09-04 10:34

是的,是不太清楚,刚接触。以为桌面就是根窗口,后来发现不是。最后切换程序时候发现了。现在用record实现,发现大家都这么用,不知道有没有更好的方法?另外还有个问题,建立一个什么都没有的窗口就要十几M内存这正常么。。
astolia 写了:
lcqtdwj 写了:我试了不行,只有鼠标在窗口内才有反应。。
astolia 写了:用python-xlib实现的简单例子,原理是一样的

代码: 全选

import Xlib.X
import Xlib.display
display = Xlib.display.Display()
root = display.screen().root
root.change_attributes(event_mask=Xlib.X.PointerMotionMask)
#root.grab_pointer(True, Xlib.X.PointerMotionMask, 1, 1, 0, 0, 0)
while True:
  if display.pending_events() > 0:
    event = display.next_event()
    if event.type == Xlib.X.MotionNotify:
      print event.root_x, event.root_y
承认吧,你不知道根窗口是什么东西,也没有仔细读我3楼写的东西,我单独标注出来好了
你想要监听的窗口设置事件掩码PointerMotionMask
我的代码里只对根窗口设置了,所以只能额外接收到根窗口的事件。你不知道根窗口在哪里,所以也接收不到事件信息
你要监听所有窗口的,又不是想成为窗口管理器的话,只有搞遍历去设置了,性能不见得比定时查询高
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 在Gtk中如何能够监听全局鼠标键盘事件?

#10

帖子 eexpress » 2014-09-04 10:54

root可不等于桌面。窗口可以查父窗口的,一直查到desktop。
● 鸣学
回复