2011年1月30日

X11 Selection Translator

Windows 下的字典軟體都異常強大,有著螢幕取詞、即時發音等大量功能 ( 像是我現在用的有道词典 )。希望在 Linux 下也有類似螢幕取詞這樣的方便功能,於是寫了這玩意兒

......不過螢幕取詞貌似相當地有難度啊 (||。3。) 翻了一下 Xlib,好像沒有相關 API 可以摳...... 所以改成實現自動翻譯滑鼠選取的文字,並在游標下顯示翻譯結果



在 X11 下,Copy & Paste 功能叫做 Selections。有分為兩種:
  • Clipboard:一般通用的。你知道的。不解釋。
  • Primary:用滑鼠選取字串時,自動將文字內容放入 buffer 內;之後可以用滑鼠中鍵貼上 buffer 內容。就是它了!

本來以為要搞低階 X Window programming 的說...... 還好想起了強大的 Qt,文檔裡還真的有 QClipboard.selectionChanged() 這個 signal 可以用 ( 包山包海,不愧是 KDE SC 的基石 ),那就可以即時地對滑鼠選取有反應啦 (>ω<)♪♪

至於翻譯部份,交給股溝提供的服務來處理。見下例: http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=python%20rocks!&langpair=en|zh-TW
可以觀察到,就是朝這網址塞進翻譯參數 ( 大段文章也可以塞 ),結果是 JSON 格式。Python 有 urllib / urllib2 可以處理網路連線,也有 json 可以 parse。

一個關鍵小技巧是去除翻譯小視窗的 window decorator 和邊框。QWidget.setWindowFlags(Qt::SplashScreen) 可以完成這件事,讓 widget 具有類似 SplashScreen 的怪異性質。用這個技巧還可以寫成背單字工具、定時自動遮掩全屏的 Anti-RSI 小程式等等,端視想像力。

( 要注意的是,翻譯小視窗還是得受到 window manager 控制...... 所以如果 WM 會自動移動新視窗的話,這程式就直接挫賽瞭~~)

最後一點,這程式是透過 SystemTray 常駐存活的,用到了兩個 icon。因為我希望把需要的資源通通搞進單一檔案內 ( 而不是又東一個西一個圖檔散了滿地 ),所以把圖檔內容轉換成 binary text 摳進程式碼,再用 QPixmap.loadFromData(data) 讀入。轉換函式大概長得像這樣:
def dump_binary(filepath):
    with open(filepath, 'rb') as f:
        content = f.read()
        output = ''
        for byte in content:
            h = hex(ord(byte))[2:]
            if len(h) == 1:
                h = '0' + h
            output += '\\x' + h
    return "'" + output + "'"
這就是程式碼開頭那兩行長串亂碼的由來......

就這樣,翻譯程式完成啦!缺點是需要網路連線,而且這個 Google API 只提供單一翻譯結果 QQ
話說,嘗試寫這玩意兒的途中還曾經用 threading 來設計...... 那蛋真是一陣一陣疼個沒完沒了啊!有空的話真該惡補一下多緒程式了 =.=

1 則留言:

  1. 大大好像也是Arch的愛好者,
    新的Arch正體中文論壇開張囉!
    http://www.archlinux-tw.ddns.info/bbs/index.php

    回覆刪除