狠狠撸

狠狠撸Share a Scribd company logo
GTK+ 陷阱与进阶技巧
     王勇
GTK+ 开发中遇到的陷阱
为什么整了半天, 多线程都不能工作?

哥, 你忘了在程序开始添加线程初始化代码了
吧?

在GTK+程序的最开始位置加入下面代码来支持
多线程开发:

 gtk.gdk.threads_init()
为什么我的自绘代码没起作用?

一般我们都通过添加信号 expose-event 回调来
自绘控件, 如果所有绘制代码都正确, 请检查
一下自绘函数是否返回 True, 比如下面代码:

def expose_event_foo(self, widget, event):
  cr = widget.window.cairo_create()
  # draw on cairo.
  return True
为什么自绘时子控件没有显示?

因为当自绘容器时返回 True, 如果不在返回
True 之前把重绘事件传递给子控件, 子控件就
没有机会调用相应的函数进行自绘, 实例代
码:

...
# draw on cairo.
propagate_expose(widget, event)
return True
propagate_expose 函数实现


def propagate_expose (widget, event):
  '''Propagate expose event to children.'''
  if "get_child" in dir(widget) and widget.get_child() !=
None:
      widget.propagate_expose(widget.get_child(), event)
怎么绘制1像素的线条?

因为Cairo默认是开启了反锯齿, 默认用
stroke 只能画出2像素的线, 有以下3种解决方
案:

1 临时关闭反锯齿
2 在目标坐标上添加 0.5 像素的偏移量
3 用 cr.rectange() 和 cr.fill() 替代 cr.stroke()
临时关闭反锯齿的代码
@contextmanager
def cairo_disable_antialias(cr):
  '''Disable cairo antialias temporary.'''
  # Save antialias.
  antialias = cr.get_antialias()
  cr.set_antialias(cairo.ANTIALIAS_NONE)
  try:
      yield
  except Exception, e:
      print 'with an cairo error %s' % e
  else:
      # Restore antialias.
      cr.set_antialias(antialias)

with cairo_disable_antialias(cr):
   ......
GTK+ 进阶技巧
怎么制作不规则的窗口?
不规则窗口的基本原理
骋迟办+陷阱与进阶技巧
GTK+ 不规则窗口代码, 步骤一:

?
?
# 创建形状位图。
x, y, w, h = rect.x, rect.y, rect.width, rect.height
bitmap = gtk.gdk.Pixmap(None, w, h, 1)
cr = bitmap.cairo_create()

?
GTK+ 不规则窗口代码, 步骤二:



# 清空画布。
cr.set_source_rgb(0.0, 0.0, 0.0)
cr.set_operator(cairo.OPERATOR_CLEAR)
cr.paint()
GTK+ 不规则窗口代码, 步骤三:



# 绘制窗口形状。
cr.set_source_rgb(1.0, 1.0, 1.0)
cr.set_operator(cairo.OPERATOR_OVER)
cr.arc(x + w / 2, y + h / 2, w / 2, 0, 2 * pi)
cr.fill()
GTK+ 不规则窗口代码, 步骤四:




# 窗口根据绘制图形裁剪窗口形状。
widget.shape_combine_mask(bitmap, 0, 0)
窗口阴影怎么做?
阴影绘制原理图
cr.clip()
怎么制作真透明的应用程序窗口?


1. 重定向窗口的 colormap 为窗口下方的屏幕
colormap。

2. 用透明色绘制整个窗口。

3 在透明的窗口上绘制不透明的控件。
透明窗口关键代码:
window.set_colormap(gtk.gdk.Screen().
get_rgba_colormap())

window.connect_after("expose-event", expose_window)

def expose_window(self, widget, event):
  cr = widget.window.cairo_create()
  rect = widget.allocation

  cr.set_source_rgba(0.0, 0.0, 0.0, 0.0)
  cr.set_operator(cairo.OPERATOR_SOURCE)
  cr.paint()

  .......
colormap tips:



因为 mplayer 是直接绘制在窗口上的, 所以
mplayer 的窗口不能用 colormap 来设置窗口透
明。
GTK+ 多线程程序设计要点



本质上GTK+是不能多线程同时访问并绘制设备,
但是我们可以通过多个非图形化线程来分离出耗
时的后台操作, 并发送图形化代码至主线程执
行来有效提高界面的响应速度和交互体验。
GTK+ 多线程原理图



               耗时
用户操作           的后
的主线程
               台计
               算
GTK+ 多线程步骤


1. 添加非图形化线程, 并传入图形回调函数。

2. 运行非图形化后台计算。

3. 当耗时计算完成时, 发送图形回调函数至主
线程执行。
发送图形回调至主线程执行

def post_gui(func):
  '''Post GUI code in main thread.'''
  def wrap(*a, **kw):
       gtk.gdk.threads_enter()
        ret = func(*a, **kw)
        gtk.gdk.threads_leave()
       return ret
  return wrap

@post_gui
def render_func(...):
怎么渐变绘制?


1. 建立线性变化范围

2. 建立线性变换

3. 绘制图形
渐变绘制关键代码

pat = cairo.LinearGradient(x, y, x, y + h)

for (pos, color) in linear_colors:
   add_color_stop_rgba(pat, pos, color)

cr.rectangle(x, y, w, h)
cr.fill()
GTK+ 代码里面充满很多陷阱和技巧, 就像一
匹烈马, 开始的时候让人很抓狂,但是一旦你
熟悉了它的性格, 你就会感觉非常顺手。

More Related Content

Similar to 骋迟办+陷阱与进阶技巧 (20)

09 creating windows phone game with cocos2d-xna
09   creating windows phone game with cocos2d-xna09   creating windows phone game with cocos2d-xna
09 creating windows phone game with cocos2d-xna
乐费 胡
?
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek
Johnson Gau
?
用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式
Fred Chien
?
LLVM introduction
LLVM introductionLLVM introduction
LLVM introduction
National Cheng Kung University
?
Introduction of Reverse Engineering
Introduction of Reverse EngineeringIntroduction of Reverse Engineering
Introduction of Reverse Engineering
YC Ling
?
全新的蚕迟5
全新的蚕迟5全新的蚕迟5
全新的蚕迟5
Yunqiao Yin
?
Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計
Kyle Lin
?
KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較
KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較
KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較
Stipc Nsysu
?
Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門
Chui-Wen Chiu
?
颁++工程实践
颁++工程实践颁++工程实践
颁++工程实践
Shuo Chen
?
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
HO-HSUN LIN
?
讓你的人工智慧更智慧 - Developer Student Clubs.pptx
讓你的人工智慧更智慧 - Developer Student Clubs.pptx讓你的人工智慧更智慧 - Developer Student Clubs.pptx
讓你的人工智慧更智慧 - Developer Student Clubs.pptx
NCUDSC
?
twMVC#27 | C# 7.0 新功能介紹
twMVC#27 | C# 7.0 新功能介紹twMVC#27 | C# 7.0 新功能介紹
twMVC#27 | C# 7.0 新功能介紹
twMVC
?
论 Python 与设计模式。
论 Python 与设计模式。论 Python 与设计模式。
论 Python 与设计模式。
勇浩 赖
?
手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)
手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)
手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)
King Hom
?
Google map api接口整理
Google map api接口整理Google map api接口整理
Google map api接口整理
lileinba
?
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
Will Huang
?
2021laravelconftwslides12
2021laravelconftwslides122021laravelconftwslides12
2021laravelconftwslides12
LiviaLiaoFontech
?
我用顿箩补苍驳辞做页游
我用顿箩补苍驳辞做页游我用顿箩补苍驳辞做页游
我用顿箩补苍驳辞做页游
yang qingchang
?
09 creating windows phone game with cocos2d-xna
09   creating windows phone game with cocos2d-xna09   creating windows phone game with cocos2d-xna
09 creating windows phone game with cocos2d-xna
乐费 胡
?
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek
Johnson Gau
?
用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式
Fred Chien
?
Introduction of Reverse Engineering
Introduction of Reverse EngineeringIntroduction of Reverse Engineering
Introduction of Reverse Engineering
YC Ling
?
Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計
Kyle Lin
?
KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較
KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較
KSDG_007_Web 編程另闢蹊徑-GWT,Dart,TypeScript介紹與比較
Stipc Nsysu
?
Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門
Chui-Wen Chiu
?
颁++工程实践
颁++工程实践颁++工程实践
颁++工程实践
Shuo Chen
?
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
HO-HSUN LIN
?
讓你的人工智慧更智慧 - Developer Student Clubs.pptx
讓你的人工智慧更智慧 - Developer Student Clubs.pptx讓你的人工智慧更智慧 - Developer Student Clubs.pptx
讓你的人工智慧更智慧 - Developer Student Clubs.pptx
NCUDSC
?
twMVC#27 | C# 7.0 新功能介紹
twMVC#27 | C# 7.0 新功能介紹twMVC#27 | C# 7.0 新功能介紹
twMVC#27 | C# 7.0 新功能介紹
twMVC
?
论 Python 与设计模式。
论 Python 与设计模式。论 Python 与设计模式。
论 Python 与设计模式。
勇浩 赖
?
手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)
手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)
手把手教你把痴颈尘改装成一个滨顿贰编程环境(图文)
King Hom
?
Google map api接口整理
Google map api接口整理Google map api接口整理
Google map api接口整理
lileinba
?
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
Will Huang
?
我用顿箩补苍驳辞做页游
我用顿箩补苍驳辞做页游我用顿箩补苍驳辞做页游
我用顿箩补苍驳辞做页游
yang qingchang
?

骋迟办+陷阱与进阶技巧