FC47 决胜命令行
出自Full Circle 中文项目主页
FC47绝胜命令行
在上一篇文章中我说过会在这一期中写一篇关于Zenity的文章,但是我发现如果没有一段又长又复杂的脚本,根本无法说明Zenity的优点。所以,我决定把Conky的话题再深入一些,介绍如何使用lua脚本来画一些图形(在这个例子里面是圆形,但是可以肯定的是其他形状也可以)。在开始之前我想先说明一下:我并不是一个lua程序员,所以一定还有更简单的实现方式,这只是我所想到的方法。
对于那些不确定我在说什么的读者,你可以看一下我发布在DeviantArt网站上Conky的截图: http://lswest.deviantart.com/#/d3ay5fb
首先,请确认你已经安装了Conky(在Ubuntu9.10中的版本是1.7.2)。在这里,我假定所有的人都使用9.10或者更高的版本。如果你的Conky版本较低,那么在launchpad上也许会有适合你的PPA源。
我们所要创建的控件包括一个简单的音乐播放器和一个时钟(就像上面抓图中的那样)。还有,因为我觉得没有必要重复画圆的动作(在这个例子里面,其实是那几个环),我将在一个现成的脚本基础上修改:http://londonali1010.deviantart.com/art/quot-Rings-quot-Meters-for-Conky-141961783。如果你想看到完整的脚本(用于参考或者修正),请看本篇文章的末尾。
代码说明
在正式开始编写脚本之前,你需要选择是将这些控件分别在两个Conky的进程中(我的选择)里加载,还是在一个进程中加载。我使用两个进程是因为我的桌面上还有另外两个Conky进程。如果我将这些控件放在一个进程中会导致重叠。如果你只想使用一个进程,那么你需要增加最小尺寸,并调整每个控件的坐标值,以便将控件放入Conky的窗口中。坐标X和Y是相对于Conky的位置的,比如:如果Conky运行的位置是(400,200)((x,y)),而控件坐标设置为(100,85),那么它显示的时候的实际位置是在(500,285)。请记住这一点。
还有,为了使用lua脚本,你必须将下面的内容加入.conkyrc文件中:
lua_load /home/lswest/conky_testing/rings-v1.2.lua lua_draw_hook_pre ring_stats
上面的第一行是lua脚本的绝对路径,下面一行则是你的主函数的名字(如果你写成了conky_ring_stats或者ring_stats,Conky会自动查找并选择匹配度最高的那个函数)。
脚本中已经有注释来说明,但我还是简单的解释一下每一行代码。name是Conky的变量名(比如${time }),而args则是参数(如${time %I}),这个变量将用在脚本(在pastebin上)的第121-131行的本地函数setup_ring中。它的主要作用就是发送命令(以${name args}的格式)到Conky,然后获得结果,之后进行运算。结果被转换为数值,计算成圆的角度(根据输入的最大度数),也就是说,如果将员平均分成360份,那每一份就是1°,如果分成12份,那么圆的每个份是2*pi/max(弧度)。即使你不知道这些也没有关系,你只需要记住如果时钟有12个小时,那么你就得将一个圆分成12份。接下来的4个变量表示背景和前景颜色,以及它们的alhpa值(透明度)。变量x和y是时钟的位置,radius是圆的半径,thickness是线条的粗细,start_angle是圆开始的角度(0°),end_angle是圆结束的角度(360°),这样我们就得到了一个完整的圆。
对于那些了解日期格式化命令的读者,他们知道参数%I是保留十位的0(如01......02),如果不需要十位的0,参数是%l。但对于这个时钟来说,我们不用需要这些参数——即使我使用参数%H(0...23),它仍能正常工作。接下来的两个圆,我画的更小,并且用于秒钟的圆还细了2个像素。最后,你可以按照右边所示的代码所示来做(在表示小时的圆后面)。
你可以看到,这些代码相当简洁。如果你可以接受用秒钟的圆来计算秒,并且不在中间显示日期,那么你已经成功了。但是如果你像我一样,想让秒钟充满最内的圆,那么你需要在“cairo_arc(cr, xc, yc, ring_r, t_arc-arc_w, t_arc+arc_w)”之前加入下面这行代码:
if pt['arg'] == '%S' then cairo_arc(cr, xc, yc, ring_r, angle_0, t_arc+arc_w) end
这行代码的作用是将开始的位置设置为angle_0(也就是12点)并执行这行代码。我最初以为需要把代码加入到else结构体中,但是看来不一定要那样,而且这可以少敲些代码,所以我也就不去理会格式是否合适了。如果你想在时钟的中间显示日期,那么需要估计一下显示的位置,并且在.conkyrc中加入下面这行代码:
${goto 115}${voffset 150}${time %A}
${goto 115}${time %b %d %Y}
goto语句的作用是向右偏移(你也可以使用${offset <pixels>}),voffset则是垂直偏移(比如,参数中的像素数是从conky窗口的顶部开始计算的偏移量)。我的例子中是将星期显示在上面一行,然后日期显示在下面一行。如果你想改变显示的方式,请在man中查找关于日期的部分。
MPD控件
在开始之前,我得说明一下这些脚本只适合MPD(Music Player Daemon),如果要让Conky适用用于其他播放器则需要进行修改。我相信你可以利用相同的技巧来使其用于其他播放器。不过我认为这没什么必要,因为其他音乐播放器本来就可以显示“当前音乐”。
播放器的全局变量设置请参照下一页左上角的代码。
正如你所想的那样,我们使用100个刻度(因为它使用百分比,取值将是0到100)。这里的变量arg同样是空值,这一点很重要,因为缺少它会使后面的函数调用出错(缺少参数)。当你完成这些代码时,你会发现一旦音乐停止,播放器就不见了。为了解决这个问题,你需要对代码做如下改动:
在文件的开始或最后加入这个函数:
function conky_my_flag(my_arg) flag = my_arg return "" end
然后,在原始脚本中找到下面的代码:
local updates=conky_parse('${updates}')
update_num=tonumber(updates)
if update_num>5 then
for i in pairs(settings_table) do
setup_rings(cr,settings_table[i])
end
end
将其放入下面的if语句中(<text from above>部分):
if tonumber(flag) == 1 then <text from above> end cairo_destroy(cr)
这样最后的11行代码将会如右上方所示。
上面的代码改动只是将在简单的使MPD不运行时不要销毁,否则正常运行这个控件。我们主要是通过在if语句里添加了一个全局变量flag来添加这个功能。现在,我们还需要在.conkyrc文件中添加${lua my_flag 0}和${lua my_flag 1}来调用这个功能并且将变量flag设置为0或者1,这是为了让MPD停止时flag为(0)而不是(1)。这段代码在.conkyrc中如上方所示。
代码所做的是工作是当_mpd_playing为false时将标记设为0,否则就设为1。其他的设置则用于显示和定位专辑名称,当MPD暂停时显示“Paused”,或者在MPD播放时在右侧分两行显示歌手和歌曲名称。代码${scroll 38 ${mpd_title}}的作用是当歌名长度超过38像素时进行滚动显示(文字自右向左滚动)。你可以不用管它,我是为了防止歌词超过我的Conky的宽度。为了显示图像,你需要在TEXT部分之前加入下面两个设置:
imlib_cache_size 0 vePortal
那下面显示的也是mpd-cover脚本的部分代码。这个mpd-cover脚本适用于python 2.X,不过你可以用2to3程序重写这部分以便在python 3下使用。如果你遇到任何困难,请与我联系。注意:有些符号会导致脚本出错。我已经做了一些修改,原始的代码这这个网站上:https://bbs.archlinux.org/viewtopic.php?id=112708
我希望大多数读者感觉这是一件有趣的事情,也欢迎大家给我提出任何建议、反馈和任何问题。如果希望联系我,你可以发邮件到lswest34@gmail.com,请在标题中注明“C&C”或者“FCM”,这样我将能够及时的查看。另外,最好使用英语或者德语,否则我就只能依赖谷歌来翻译了。如果有人对代码做了改善,请发给我一份,并说明一下修改的原因,这样我就在下一期中的文章中介绍给感兴趣的读者了。
Scripts:
http://pastebin.com/SpC6bcn7 Lua clock ring
http://pastebin.com/iZFdZAeg Conky mpd
http://pastebin.com/zkVVHkYk .conkyl_mpd
http://pastebin.com/BDa5MHuR conkyrc for clock
http://pastebin.com/ZX4pLbta mpd-cover script