pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
- langyxxl
- 帖子: 443
- 注册时间: 2012-01-17 22:17
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
你干脆把你的代码放出来,我们下载,直接看看,说不定能帮你修改对..
-
- 帖子: 20
- 注册时间: 2009-11-25 19:40
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
- 附件
-
- test.rar
- (3.04 KiB) 已下载 96 次
-
- 帖子: 482
- 注册时间: 2013-09-13 0:42
- 系统: Debian sid
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
你这种需要算是实时显示~ 上面提到的方法需要变通一下的, 好吧, 我的错, 话只说了一半.niuminguo 写了:这个方法我试过了,虽然不抖动了,但是移动不平滑,像是鼠标指针先移动过去了,窗口才过去,不是同步移动的。改变timeout值也不行,改的太小的时候又会出现抖动。niuminguo 写了:非常感谢你的答复,你提到的方法我再试试看。另外,pygobject的东西我也会看看,非常重要的提醒,多谢!nae6taiyie0T 写了:因为你用的是实时计算, 当窗口移动后, 你绑定的操作都会被计算一遍, 这样有很大的计算量, 表现出来就是卡, 抖.niuminguo 写了:代码如下:
[/size]代码: 全选
#!/usr/bin/env python import gtk class TitleBar(gtk.DrawingArea): def __init__(self,father): gtk.DrawingArea.__init__(self) self.motion='' self.begin_x='' self.begin_y='' self.end_x='' self.end_y='' self.father=father self.father_x,self.father_y=self.father.get_position() self.set_size_request(-1,80) self.connect('button-press-event',self.mouse_press) self.connect('button-release-event',self.mouse_release) self.set_events( gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK) def mouse_press(self,widget,event): if event.button == 1: self.begin_x,self.begin_y = event.x,event.y self.motion=self.connect('motion-notify-event',self.mouse_motion) def mouse_release(self,widget,event): self.disconnect(self.motion) def mouse_motion(self,widget,event): self.end_x,self.end_y = event.x,event.y x=self.father_x + int(self.end_x - self.begin_x) y=self.father_y + int(self.end_y - self.begin_y) self.father.move(int(x),int(y))
self.father是drawingarea所在的窗体。目的是通过鼠标在drawingarea上拖动来拖动窗体移动。效果是可以拖动窗体移动,但是抖动的比较厉害。
我的解决方法是用延时计算, 原理很简单, 这也是做GUI设计的一个基本技巧.
当移动事件触发之后, 你用GLib.timeout_add()来调用你真正的处理函数. 看例子:适用的场景包括, 播放器的进度条的滑动, 窗口移动; 还有, 输入框的自动补全(自动完成)等.代码: 全选
def on_window_move(self, *args): def _on_window_move(local_timestamp): # 如果这两个时间标记不相同, 就什么都不做. if local_timestamp != self.window_move_timestamp: return # 超过250ms, 进行实际的计算操作 # .... self.window_move_timestamp = time.time() GLib.timeout_add(250, _on_window_move, self.window_move_timestamp)
当然, 这个方法对于需要实时得到窗口状态的操作不适用, 比如实时显示当前窗口的位置.
恰当地处理好时间, 在GUI设计中是很有意思的, 比如, 在手机上, 如何才能取消刚刚要发送的一条短信呢? 最简单的方法就是延迟几秒钟才发送(这个地在老罗他们的android ROM里加入的功能).
多说两句无关的, Gtk中提供的另一个简单易用的函数是GLib.idle_add(), 用它可以将后台线程处理好的数据转到主线程上显示.
还有, 提醒一下, pygtk这个gtk的绑定早在2011年就没更新了, 最后一个版本是2.24. 现在都转到了PyGObject上来了, 总体来说, 后者的API更加规范一下, 并且更强大, 具体可以看一下GObject Introspection.
用过gnumeric吗? 里面的绘制的图形, 移动起来速度特别快, 完全不卡, 因为它使用了部分渲染的技巧: 图片随着鼠标移动时, 先只绘制四个边框(用虚线), 然后当用户放开鼠标时, 再将图片的内容重新绘制出来.
这种技巧, 极大地减少了计算量.
一个反例就是inkscape, 它里面的矢量图, 包括路径, 都是实时绘制的, 一个稍复杂的操作, CPU就跑到了100%(我的笔记本性能不太好).
-
- 帖子: 482
- 注册时间: 2013-09-13 0:42
- 系统: Debian sid
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
-
- 帖子: 482
- 注册时间: 2013-09-13 0:42
- 系统: Debian sid
-
- 帖子: 482
- 注册时间: 2013-09-13 0:42
- 系统: Debian sid
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
好吧, 我还是比较活跃的.
看了你的代码, 找到了错误.
你对event.x, event.x_root等距离有错误的理解, 不多说, 先上代码, 压缩包里有完整的修改后的代码, 以及我用gtk3重写的代码, 我建议你直接学PyGObject, pygtk确实过时了.
用gtk3重写的那个, 还加入了一个小特性, 当鼠标按下时鼠标会变成手形, 松开后又会恢复.
多数linux窗口管理器会提供一个很好的功能, 就是按住Alt键 再拖鼠标, 就可以移动窗口了.
如果你还想在ToolBar上面放一些按纽的话, 就真不推荐你这样写代码了, 因为在gtk3中, ToolBar可以直接拖放的, 请试试evince, nautilus你就会发现了. 至于GtkToolBar的背景, 也可以用图片来填充的, 可以在CSS中定义background-image. 是的, gtk3中可以直接用CSS来定义widget的style, 写起来很容易上手.
手动计算window position并不推荐, 没有必要, 因为gtk提供了类似的函数, gtk_window_begin_move_drag(), 还有一个类似的gtk_window_begin_resize_drag(), 这个是调整窗口大小的. 具体的用法可以参考devhelp里的解释.
也可以看一下我之前的一个小项目: https://github.com/LiuLang/gmeasure, 桌面上的测量工具, 类似于screenruler等, 但它的背景是可调节成透明的, 它有x, y两个轴, 很方便. 里面有用到上面说的两个函数, 代码很短, 不到200行.
我之前回答的那些, 太多余了, 因为我当时没读你的代码, 并没有找到根本的问题, 就算是胡扯吧.
看了你的代码, 找到了错误.
你对event.x, event.x_root等距离有错误的理解, 不多说, 先上代码, 压缩包里有完整的修改后的代码, 以及我用gtk3重写的代码, 我建议你直接学PyGObject, pygtk确实过时了.
用gtk3重写的那个, 还加入了一个小特性, 当鼠标按下时鼠标会变成手形, 松开后又会恢复.
多数linux窗口管理器会提供一个很好的功能, 就是按住Alt键 再拖鼠标, 就可以移动窗口了.
如果你还想在ToolBar上面放一些按纽的话, 就真不推荐你这样写代码了, 因为在gtk3中, ToolBar可以直接拖放的, 请试试evince, nautilus你就会发现了. 至于GtkToolBar的背景, 也可以用图片来填充的, 可以在CSS中定义background-image. 是的, gtk3中可以直接用CSS来定义widget的style, 写起来很容易上手.
手动计算window position并不推荐, 没有必要, 因为gtk提供了类似的函数, gtk_window_begin_move_drag(), 还有一个类似的gtk_window_begin_resize_drag(), 这个是调整窗口大小的. 具体的用法可以参考devhelp里的解释.
也可以看一下我之前的一个小项目: https://github.com/LiuLang/gmeasure, 桌面上的测量工具, 类似于screenruler等, 但它的背景是可调节成透明的, 它有x, y两个轴, 很方便. 里面有用到上面说的两个函数, 代码很短, 不到200行.
我之前回答的那些, 太多余了, 因为我当时没读你的代码, 并没有找到根本的问题, 就算是胡扯吧.
- 附件
-
- test-mod.tar.gz
- 修正好的代码
- (20 KiB) 已下载 98 次
-
- 帖子: 20
- 注册时间: 2009-11-25 19:40
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
不好意思,我刚开始用的tgz格式的,结果上传时发现不支持。所以误认为其他格式也不支持才用了rar.nae6taiyie0T 写了:请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
- 附件
-
- test.tar.gz
- (3.11 KiB) 已下载 95 次
-
- 帖子: 20
- 注册时间: 2009-11-25 19:40
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
不好意思,我刚开始用的tgz格式的,结果上传时发现不支持。所以误认为其他格式也不支持才用了rar.nae6taiyie0T 写了:请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
- 附件
-
- test.tar.gz
- (3.11 KiB) 已下载 96 次
-
- 帖子: 482
- 注册时间: 2013-09-13 0:42
- 系统: Debian sid
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
测试结果如何? 有问题的话就说出来吧.niuminguo 写了:不好意思,我刚开始用的tgz格式的,结果上传时发现不支持。所以误认为其他格式也不支持才用了rar.nae6taiyie0T 写了:请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
-
- 帖子: 20
- 注册时间: 2009-11-25 19:40
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
太好了,可以拖动了。看来还是我理解上的错误,浪费了大家这么多时间,实在不好意思啊。多谢了,现在开始学习pygobject。另外,你用gtk3实现的那个手型的小特性也超级赞!太谢谢你了!nae6taiyie0T 写了:测试结果如何? 有问题的话就说出来吧.niuminguo 写了:不好意思,我刚开始用的tgz格式的,结果上传时发现不支持。所以误认为其他格式也不支持才用了rar.nae6taiyie0T 写了:请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
-
- 帖子: 482
- 注册时间: 2013-09-13 0:42
- 系统: Debian sid
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
嘻嘻~niuminguo 写了:太好了,可以拖动了。看来还是我理解上的错误,浪费了大家这么多时间,实在不好意思啊。多谢了,现在开始学习pygobject。另外,你用gtk3实现的那个手型的小特性也超级赞!太谢谢你了!nae6taiyie0T 写了:测试结果如何? 有问题的话就说出来吧.niuminguo 写了:不好意思,我刚开始用的tgz格式的,结果上传时发现不支持。所以误认为其他格式也不支持才用了rar.nae6taiyie0T 写了:请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
关于pygobject的资料, 给你推荐一些.
基础的: https://python-gtk-3-tutorial.readthedo ... index.html
cairo方面的:http://zetcode.com/gfx/pycairo/ , 因为gtk中可以很方便地使用cairo, 用于2D绘图的, 命令也简单.
参考书的话, http://www.gtkbook.com/ , Foundations of GTK+ Development, 英文版, 比较旧了, 基于gtk2的, 但里面对gtk有了详细的讲解, 我入门时读的这本书, 只能说, 关于gtk的参考书真的不多, 但是它很容易入手, 再加入容易查API, 开发起来也不难.
工具的话, 我写PyGObject用的是vim.
当然了, devhelp, glade这几个也是必需的.
如果要使用dbus的话, 还要加上d-feet这个dbus浏览器
-
- 帖子: 20
- 注册时间: 2009-11-25 19:40
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
好的,多谢了啊,太感谢你了。:)nae6taiyie0T 写了:嘻嘻~niuminguo 写了:太好了,可以拖动了。看来还是我理解上的错误,浪费了大家这么多时间,实在不好意思啊。多谢了,现在开始学习pygobject。另外,你用gtk3实现的那个手型的小特性也超级赞!太谢谢你了!nae6taiyie0T 写了:测试结果如何? 有问题的话就说出来吧.niuminguo 写了:不好意思,我刚开始用的tgz格式的,结果上传时发现不支持。所以误认为其他格式也不支持才用了rar.nae6taiyie0T 写了:请换成tar.gz, zip, 7z, bz2等压缩格式, 谢谢~niuminguo 写了:把代码删改了下,取了相关部分,打包。下载后解压,然后python test.py来运行。蓝色标题栏是用来拖动的。
关于pygobject的资料, 给你推荐一些.
基础的: https://python-gtk-3-tutorial.readthedo ... index.html
cairo方面的:http://zetcode.com/gfx/pycairo/ , 因为gtk中可以很方便地使用cairo, 用于2D绘图的, 命令也简单.
参考书的话, http://www.gtkbook.com/ , Foundations of GTK+ Development, 英文版, 比较旧了, 基于gtk2的, 但里面对gtk有了详细的讲解, 我入门时读的这本书, 只能说, 关于gtk的参考书真的不多, 但是它很容易入手, 再加入容易查API, 开发起来也不难.
工具的话, 我写PyGObject用的是vim.
当然了, devhelp, glade这几个也是必需的.
如果要使用dbus的话, 还要加上d-feet这个dbus浏览器
- langyxxl
- 帖子: 443
- 注册时间: 2012-01-17 22:17
Re: pygtk 实现的无边框窗口的拖动 拖动时窗口抖动太厉害 不平滑
感觉学到了很多.....
大神,就是不一样啊!!
大神,就是不一样啊!!