2月7
在KDE-4.2发布之后,我立刻就emerge了,使用后的感受只能用惊艳来形容,这段时间也基本上使用kde-4.2作为日常桌面。不过还是有遗憾的,因为lrcShow-II不能在amarok2上使用。所幸的是,这段时间单位里并不是很忙,下班的也早,因此有点时间来解决这个问题。

初步的想法是这样的,原先lrcShow-II中采用独立GUI进程,并且启动一个线程用于监听amarok发出的信号。那么当下amarok已经不再支持非qtscript的脚本了,因此这个线程只能放弃原先的接收stdin的方式,转向dbus。我对dbus并不熟悉,除了大致上“他是什么”外,基本上一无所知了,好在开发伙伴意大利的OutLikeAShoe曾经发给我一份使用dbus的测试代码,那我也就依样画葫芦,把dbus部分替代原先的stdin部分即可。采用dbus有个好处,只要是支持mpris 1.0规范的播放器,那都是可以支持的,包括audacious、xmms2等等。

不过事情的发展并不像原先预计的那样顺利。因为我发现在线程中运行的dbus监听信号的事件循环,居然block了主进程的GUI循环,这实在难以想象,这可是在线程中啊,这也会?很遗憾的是,这个问题整整困扰了我一个礼拜,代码上没有什么变动,在这个关口上迟迟没有突破,一直是google,或者有点眉目后发邮件请教。

今天原先想打破原来的代码结构,采用多进程的方式来解决了,不过就在心灰意冷的时候,突然google到了一篇关于dbus API介绍的文章,在介绍dbus.mainloop.glib的thread_init()方法中提到,如果需要在第二个线程中启动dbus事件循环,首先要调用该方法。于是乎,立刻在程序中添加如下代码:

from dbus.mainloop.glib import threads_init
...
...

def mainQt4(args):
  threads_init()
  app=QApplication(args)
  win=mainBox()
  win.show()
  sys.exit(app.exec_())


不过运行后出现以下错误:

** ERROR **: g_thread_init() must be called before dbus_threads_init()
aborting...                                                          
已放弃


好在线索充分,于是立刻google “g_thread_init()“,立刻有了答案,于是代码修改为:

from dbus.mainloop.glib import threads_init
import gobject
...
...

def mainQt4(args):
  gobject.threads_init()
  threads_init()
  app=QApplication(args)
  win=mainBox()
  win.show()
  sys.exit(app.exec_())


运行后成功了!

这里没办法讲深层次原因,实在自己了解太少了,好在突破了这个瓶颈,lrcShow-II的移植工作应该不会再有太大的问题了。初步将这个程序命名为lrcShow-X,其中X代表一切带有dbus接口、符合mpris 1.0规范的所有媒体播放器。

已经在kdecn的论坛上做了预告并上了最新截图,这里就不上了。

2 条评论 to “dbus事件循环与GUI事件循环冲突的解决”

123坐 说:
2010/02/09 15:52
不错,学习了
oldherl 说:
2009/02/17 20:36
要是界面和核心能分离就好了,那样当作exaile或者audacious插件时就可以使用gtk界面了……
admin 回复于 2009/02/18 20:27
严格意义上的核心、界面分离是不可能的,替换掉qt的ui文件用gtk的,就一下子变成gtk程序了?
目前lrcShow-X可以支持audacious,略有小bug,不影响使用。而且目前qt4.5支持gtk风格
分页: 1/1 第一页 1 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]