PyGobject(三十一)布局容器之EventBox
2016-07-28 11:09
567 查看
GtkEventBox
继承关系
Methods
Virtual Methods
Properties
Signals
例子
捕捉鼠标按键事件
二
附录
GdkEventButton
Fields
代码:
代码解析:
创建一个Gtk.EventBox
连接Gtk.Widget::button_press_event(widget, event)信号
在on_button_press_event方法中,先判断事件(Gdk.EventButton)的类别是否为按键,
再判断按下的键是哪一个
代码
关于画图可参见Cairo系列
代码下载地址:http://download.csdn.net/detail/a87b01c14/9594728
继承关系
Methods
Virtual Methods
Properties
Signals
例子
捕捉鼠标按键事件
二
附录
GdkEventButton
Fields
Gtk.EventBox
Gtk.EventBox有自己的窗口。对于那些没有自己窗口的部件捕捉事件是非常有用的继承关系
Gtk.EventBox是Gtk.Bin的直接子类Methods
方法修饰词 | 方法名及参数 |
---|---|
static | new () |
get_above_child () | |
get_visible_window () | |
set_above_child (above_child) | |
set_visible_window (visible_window) |
Virtual Methods
Properties
Name | Type | Flags | Short Description |
---|---|---|---|
above-child | bool | r/w/en | Whether the event-trapping window of the eventbox is above the window of the child widget as opposed to below it. |
visible-window | bool | r/w/en | Whether the event box is visible, as opposed to invisible and only used to trap events. |
Signals
Name | Short Description |
---|
例子
捕捉鼠标按键事件
代码:
#!/usr/bin/env python3 # Created by xiaosanyu at 16/7/12 # section 037 # # author: xiaosanyu # website: yuxiaosan.tk \ # http://blog.csdn.net/a87b01c14 # created: 16/7/12 TITLE = "EventBox" DESCRIPTION = """ The Gtk.EventBox widget is a subclass of Gtk.Bin which also has its own window. It is useful since it allows you to catch events for widgets which do not have their own window. """ import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk class EventBoxWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="EventBox Example") self.set_size_request(200, 200) self.set_border_width(10) box = Gtk.VBox() label = Gtk.Label("press your mouse.") box.add(label) label = Gtk.Label() box.add(label) eventbox = Gtk.EventBox() eventbox.connect("button-press-event", self.on_button_press_event, label) eventbox.add(box) self.add(eventbox) @staticmethod def on_button_press_event(widget, event, label): # Check if right mouse button was preseed if event.type == Gdk.EventType.BUTTON_PRESS: if event.button == Gdk.BUTTON_PRIMARY: label.set_label("you press The left mouse button") if event.button == Gdk.BUTTON_MIDDLE: label.set_label("you press The middle mouse button") if event.button == Gdk.BUTTON_SECONDARY: label.set_label("you press The right mouse button") def main(): win = EventBoxWindow() win.connect("delete-event", Gtk.main_quit) win.show_all() Gtk.main() if __name__ == "__main__": main()
代码解析:
创建一个Gtk.EventBox
eventbox = Gtk.EventBox()
连接Gtk.Widget::button_press_event(widget, event)信号
eventbox.connect("button-press-event", self.on_button_press_event, label)
在on_button_press_event方法中,先判断事件(Gdk.EventButton)的类别是否为按键,
再判断按下的键是哪一个
二
代码
#!/usr/bin/env python3 # Created by xiaosanyu at 16/7/12 # section 038 # Event Axes # Demonstrates advanced handling of event information from exotic # input devices. # # On one hand, this snippet demonstrates management of input axes, # those contain additional information for the pointer other than # X/Y coordinates. # # Input axes are dependent on hardware devices, on linux/unix you # can see the device axes through xinput list <device>. Each time # a different hardware device is used to move the pointer, the # master device will be updated to match the axes it provides, # these changes can be tracked through GdkDevice::changed, or # checking gdk_event_get_source_device(). # # On the other hand, this demo handles basic multitouch events, # each event coming from an specific touchpoint will contain a # GdkEventSequence that's unique for its lifetime, so multiple # touchpoints can be tracked. # author: xiaosanyu # website: yuxiaosan.tk \ # http://blog.csdn.net/a87b01c14 # created: 16/7/12 TITLE = "EventBox(1)" DESCRIPTION = "" import gi import cairo gi.require_version('Gtk', '3.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Gtk, Gdk, GLib, PangoCairo, GObject class AxesInfo(object): def __init__(self, event=None, last_source=None, last_tool=None, axes=None, color=None, x=None, y=None): # GObject.GObject.__init__(self) self.event = event self.last_source = last_source # Gdk.Device self.last_tool = last_tool # Gdk.DeviceTool self.axes = axes # [Gdk.EventMotion.axes] or [Gdk.EventButton.axes] self.color = color # Gdk.RGBA self.x = x # double self.y = y # double class EventData(object): def __init__(self, pointer_info=None, touch_info=None): # GObject.GObject.__init__(self) self.pointer_info = pointer_info # dict {Gdk.Device} self.touch_info = touch_info # dict {Gdk.EventSequence} colors = ("black", "orchid", "fuchsia", "indigo", "thistle", "sienna", "azure", "plum", "lime", "navy", "maroon", "burlywood") cur_color = 0 class EventBoxWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="Event Axes") self.set_default_size(400, 400) eventbox = Gtk.EventBox() eventbox.set_support_multidevice(True) eventbox.add_events( Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK | Gdk.EventMask.ENTER_NOTIFY_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.TOUCH_MASK) event_data = self.event_data_new() eventbox.connect("event", self.event_cb, event_data) eventbox.connect("draw", self.draw_cb, event_data) self.add(eventbox) @staticmethod def axes_info_new(): global cur_color info = AxesInfo() info.color = Gdk.RGBA.from_color(Gdk.Color.parse(colors[cur_color])[1]) cur_color = (cur_color + 1) % len(colors) return info @staticmethod def event_data_new(): data = EventData() data.pointer_info = {} data.touch_info = {} return data def update_axes_from_event(self, event, data): device = event.get_device() source_device = event.get_source_device() sequence = event.get_event_sequence() tool = event.get_device_tool() if event.type == Gdk.EventType.TOUCH_END or event.type == Gdk.EventType.TOUCH_CANCEL: return data.touch_info.pop(sequence, False) elif event.type == Gdk.EventType.LEAVE_NOTIFY: return data.pointer_info.pop(device, False) if not sequence: info = data.pointer_info.get(device, None) if not info: info = self.axes_info_new() data.pointer_info.setdefault(device, info) else: info = data.touch_info.get(sequence, None) if not info: info = self.axes_info_new() data.touch_info.setdefault(sequence, info) info.event = event if info.last_source != source_device: info.last_source = source_device if info.last_tool != tool: info.last_tool = tool info.axes = None if event.type == Gdk.EventType.TOUCH_BEGIN or event.type == Gdk.EventType.TOUCH_UPDATE: if sequence and event.touch.emulating_pointer: data.pointer_info.remove(device) if event.type == Gdk.EventType.MOTION_NOTIFY: info.axes = [event.motion.axes for _ in range(source_device.get_n_axes())] elif event.type == Gdk.EventType.BUTTON_PRESS or event.type == Gdk.EventType.BUTTON_RELEASE: info.axes = [event.button.axes for _ in range(source_device.get_n_axes())] rlt, info.x, info.y = event.get_coords() def event_cb(self, widget, event, user_data): self.update_axes_from_event(event, user_data) widget.queue_draw() return False @staticmethod def render_arrow(cr, x_diff, y_diff, label): cr.save() cr.new_path() cr.move_to(0, 0) cr.line_to(x_diff, y_diff) cr.stroke() cr.move_to(x_diff, y_diff) cr.show_text(label) cr.restore() @staticmethod def draw_axes_info(widget, cr, info, allocation): axes = info.last_source.get_axes() cr.save() cr.set_line_width(1) Gdk.cairo_set_source_rgba(cr, info.color) cr.move_to(0, info.y) cr.line_to(allocation.width, info.y) cr.move_to(info.x, 0) cr.line_to(info.x, allocation.height) cr.stroke() cr.translate(info.x, info.y) if not info.axes: cr.restore() return if axes & Gdk.AxisFlags.PRESSURE: _, pressure = info.event.get_axis(Gdk.AxisUse.PRESSURE) pattern = cairo.RadialGradient(0, 0, 0, 0, 0, 100) pattern.add_color_stop_rgba(pressure, 1, 0, 0, pressure) pattern.add_color_stop_rgba(1, 0, 0, 1, 0) cr.set_source(pattern) cr.arc(0, 0, 100, 0, 2 * GLib.PI) cr.fill() if axes & Gdk.AxisFlags.XTILT and axes & Gdk.AxisFlags.YTILT: _, tilt_x = info.last_source.get_axis(Gdk.AxisUse.XTILT) _, tilt_y = info.event.get_axis(Gdk.AxisUse.YTILT) EventBoxWindow.render_arrow(cr, tilt_x * 100, tilt_y * 100, "Tilt") if axes & Gdk.AxisFlags.DISTANCE: dashes = (5.0, 5.0) _, distance = info.event.get_axis(Gdk.AxisFlags.DISTANCE) cr.save() cr.move_to(distance * 100, 0) cr.set_source_rgb(0.0, 0.0, 0.0) cr.set_dash(dashes, 2, 0.0) cr.arc(0, 0, distance * 100, 0, 2 * GLib.PI) cr.stroke() cr.move_to(0, -distance * 100) extents = cr.text_extents("Distance") cr.rel_move_to(-extents.width / 2, 0) cr.show_text("Distance") cr.move_to(0, 0) cr.restore() if axes & Gdk.AxisFlags.WHEEL: _, wheel = info.event.get_axis(Gdk.AxisUse.WHEEL) cr.save() cr.set_line_width(10) cr.set_source_rgba(0, 0, 0, 0.5) cr.new_sub_path() cr.arc(0, 0, 100, 0, wheel * 2 * GLib.PI) cr.stroke() cr.restore() if axes & Gdk.AxisFlags.ROTATION: _, rotation = info.event.get_axis(Gdk.AxisUse.ROTATION) rotation *= 2 * GLib.PI cr.save() cr.rotate(- GLib.PI / 2) cr.set_line_cap(cairo.LINE_CAP_ROUND) cr.set_line_width(5) cr.new_sub_path() cr.arc(0, 0, 100, 0, rotation) cr.stroke() cr.restore() if axes & Gdk.AxisFlags.SLIDER: _, slider = info.event.get_axis(Gdk.AxisUse.SLIDER) cr.save() cr.move_to(0, -10) cr.rel_line_to(0, -50) cr.rel_line_to(10, 0) cr.rel_line_to(-5, 50) cr.close_path() cr.clip_preserve() pattern = cairo.LinearGradient(0, -10, 0, -60) pattern.add_color_stop_rgb(0, 0, 1, 0) pattern.add_color_stop_rgb(1, 1, 0, 0) cr.set_source(pattern) mask = cairo.LinearGradient(0, -10, 0, -60) mask.add_color_stop_rgba(0, 0, 0, 0, 1) mask.add_color_stop_rgba(slider, 0, 0, 0, 1) mask.add_color_stop_rgba(slider, 0, 0, 0, 0) mask.add_color_stop_rgba(1, 0, 0, 0, 0) cr.mask(mask) cr.set_source_rgb(0, 0, 0) cr.stroke() cr.restore() if axes & Gdk.AxisFlags.X and axes & Gdk.AxisFlags.Y: # Tilt cr.save() _, tilt_x = info.event.get_axis(Gdk.AxisUse.X) _, tilt_y = info.event.get_axis(Gdk.AxisUse.Y) EventBoxWindow.render_arrow(cr, tilt_x, tilt_y, "Tilt") cr.restore() # pressure cr.save() _, pressure = info.event.get_axis(Gdk.AxisUse.X) pattern = cairo.RadialGradient(0, 0, 0, 0, 0, 100) pattern.add_color_stop_rgba(pressure, 1, 0, 0, pressure) pattern.add_color_stop_rgba(1, 0, 0, 1, 0) cr.set_source(pattern) cr.arc(0, 0, 50, 0, 2 * GLib.PI) cr.fill() cr.restore() # dashes dashes = (5.0, 5.0) _, distance = info.event.get_axis(Gdk.AxisUse.X) cr.save() cr.move_to(distance, 0) cr.set_dash(dashes) cr.arc(0, 0, distance, 0, 2 * GLib.PI) cr.stroke() cr.move_to(0, -distance) extents = cr.text_extents("Distance") cr.rel_move_to(-extents[3] / 2, 0) cr.show_text("Distance") cr.move_to(0, 0) cr.restore() # slider slider = 1 cr.save() cr.move_to(0, -10) cr.rel_line_to(0, -50) cr.rel_line_to(10, 0) cr.rel_line_to(-5, 50) cr.close_path() cr.clip_preserve() pattern = cairo.LinearGradient(0, -10, 0, -60) pattern.add_color_stop_rgb(0, 0, 1, 0) pattern.add_color_stop_rgb(1, 1, 0, 0) cr.set_source(pattern) mask = cairo.LinearGradient(0, -10, 0, -60) mask.add_color_stop_rgba(0, 0, 0, 0, 1) mask.add_color_stop_rgba(slider, 0, 0, 0, 1) mask.add_color_stop_rgba(slider, 0, 0, 0, 0) mask.add_color_stop_rgba(1, 0, 0, 0, 0) cr.mask(mask) cr.set_source_rgb(0, 0, 0) cr.stroke() cr.restore() # cr.save() cr.set_line_cap(cairo.LINE_CAP_ROUND) cr.set_line_width(5) cr.new_sub_path() cr.arc(0, 0, 120, 0, 2 * GLib.PI) cr.stroke() cr.restore() cr.restore() @staticmethod def tool_type_to_string(tool_type): if tool_type == Gdk.InputSource.PEN: return "Pen" elif tool_type == Gdk.InputSource.ERASER: return "Eraser" elif tool_type == Gdk.InputSource.BRUSH: return "Brush" elif tool_type == Gdk.InputSource.PENCIL: return "Pencil" elif tool_type == Gdk.InputSource.AIRBRUSH: return "Airbrush" elif tool_type == Gdk.InputSource.MOUSE: return "Mouse" elif tool_type == Gdk.InputSource.LENS: return "Lens cursor" elif tool_type == Gdk.InputSource.UNKNOWN: return "Unknown" else: return "Unknown" @staticmethod def draw_device_info(widget, cr, sequence, y, info): cr.save() string = "Source: " + info.last_source.get_name() if sequence: string += "\nSequence: " + str(sequence) if info.last_tool: tool_type = EventBoxWindow.tool_type_to_string(info.last_tool.get_tool_type()) serial = info.last_tool.get_serial() string += "\nTool: " + tool_type if serial != 0: string += ", Serial: %lx" % serial cr.move_to(10, y) layout = widget.create_pango_layout(string) PangoCairo.show_layout(cr, layout) cr.stroke() height = layout.get_pixel_size()[1] Gdk.cairo_set_source_rgba(cr, info.color) cr.set_line_width(10) cr.move_to(0, y) y = y + height cr.line_to(0, y) cr.stroke() cr.restore() return y def draw_cb(self, widget, cr, user_data): y = 0 data = user_data allocation = widget.get_allocation() # Draw Abs info for key, value in data.pointer_info.items(): # run this self.draw_axes_info(widget, cr, value, allocation) for key, value in data.touch_info.items(): self.draw_axes_info(widget, cr, value, allocation) # Draw name, color legend and misc data for key, value in data.pointer_info.items(): # run this self.draw_device_info(widget, cr, None, y, value) for key, value in data.touch_info.items(): self.draw_device_info(widget, cr, key, y, value) return False def main(): win = EventBoxWindow() win.connect("delete-event", Gtk.main_quit) win.show_all() Gtk.main() if __name__ == "__main__": main()
关于画图可参见Cairo系列
附录
Gdk.EventButton
Fields
Name | Type | Access | Description |
---|---|---|---|
axes | float | r/w | 移动到设备的(x,y)位置, 如果设备为鼠标这个值为None. |
button | int | r/w | 按下或释放的键值 值为1到5。通常1是鼠标左键, 2是中间键, 3是右键. |
device | Gdk.Device | r/w | the master device that the event originated from. Use Gdk.Event.get_source_device() to get the slave device. |
send_event | int | r/w | True if the event was sent explicitly. |
state | Gdk.ModifierType | r/w | a bit-mask representing the state of the modifier keys (e.g. Control, Shift and Alt) and the pointer buttons. See Gdk.ModifierType. |
time | int | r/w | 鼠标点击时的时间 |
type | Gdk.EventType | r/w | 事件的类别. |
window | Gdk.Window | r/w | the window which received the event. |
x | float | r/w | 相对于依附的window的x轴位置. |
x_root | float | r/w | 相对于屏幕的x轴位置. |
y | float | r/w | 相对于依附的window的y轴位置. |
y_root | float | r/w | 相对于屏幕的y轴位置. |
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法