8

自宅のKubuntuマシンでは、この洞察に満ちたページを基に、どのウィンドウやアプリケーションにフォーカスがあるかに関係なく、キーを押すたびにビープ音を鳴らすスクリプトを実行しています。

#!/usr/bin/env python 

from Xlib.display import Display
import os
import sys

ZERO=[]
for i in range(0,32):
        ZERO.append(0)
ignorelist=[ZERO]

def main():    
        if os.getuid()==0:
                os.system("modprobe pcspkr")
                print("Speaker enabled, start as normal user")
                sys.exit()

        print("If no beep is heard, then run as root to enable pcspkr")

        disp = Display()
        while 1:
                keymap=disp.query_keymap()
                if keymap not in ignorelist:
                        os.system("beep")

if __name__ == '__main__':
        main()

このスクリプトはうまく機能しますが、デュアルコアIntelマシンの両方のCPUをそれぞれ約80%に固定しているため、このマシンで他にできることはほとんどありません。この単純なスクリプトの動作を妨げることなく、CPU要件を減らすにはどうすればよいですか?つまり、どのウィンドウまたはアプリケーションにフォーカスがあるかに関係なく、キーを押した瞬間にビープ音が鳴るはずです。

Pythonでこれが不可能な場合、他にどのようなテクノロジーを検討する必要がありますか?C?キーが押されたことをアプリケーションに通知するカーネルコンポーネントが存在すると思います。KDEは他にどのようにグローバルショートカットを処理しますか?アプリケーションにこれらの通知も受信させるにはどうすればよいですか?

目標は、各キーが押された瞬間にビープ音を鳴らすことです。これは、キーを押すのを逃さずに、ボトムアウトせずにメカニカルキーボードで入力するように指をトレーニングしているためです。CherryBrownsからCherryBluesに卒業したばかりですが、戦術的なフィードバックがないため、慣れるまでに少し時間がかかります。

どのウィンドウにフォーカスがあるかに関係なく、ソリューションはビープ音を鳴らさなければならないことに注意してください。このプログラムは、私が使用するすべてのアプリケーションのバックグラウンドで実行されるデーモンとして使用することを目的としています。

ありがとう。

4

5 に答える 5

12

イベントを使用する:

import Xlib
from Xlib.display import Display

display = Display()

screen = display.screen()
w = screen.root.create_window(0, 0, 100, 100, 1,
              screen.root_depth,
              event_mask = Xlib.X.KeyPressMask)
w.map()

while True:
    event = display.next_event()
    if event.type != Xlib.X.KeyPress:
        continue
    print "OHAI"

詳細はhttp://python-xlib.sourceforge.net/doc/html/python-xlib_10.html#SEC9から取得

于 2012-08-16T15:31:41.477 に答える
8

whileループは可能な限り高速に実行されるため、CPUのすべてのサイクルを消費しています。小さなsleep()遅延を追加することもできますが、いくつかの重要なイベントを見逃すリスクがあります。または、pyhookモジュールを使用してキーの押下を監視することを検討してください。

于 2012-08-16T15:32:33.883 に答える
7

niceを使用してスクリプトを開始できます。niceコマンドはスクリプトの優先度を下げるので、システムが他に何もすることがない場合にのみスクリプトが実行されます。そうすれば、CPUサイクルを消費しますが、システムを他のタスクに通常どおり使用できます。

詳細については、manページを参照してください。

編集:

CPU使用率を減らすために、time.sleep(0.01)を使用して、わずかな遅延を追加できます。これによりCPUの負荷は軽減されますが、キーを押してからビープ音が鳴るまでの時間がわずかに長くなります。

于 2012-09-12T09:37:27.520 に答える
5

プログラムがCPUを占有しているのは、キーが押されていなくても、ミリ秒ごとにキーボードのステータスをチェックすることでCPUをビジー状態に保つ無限ループを実行しているためです。コンピュータには停止できる兆候がないため、可能な限り頻繁にチェックを続け、それによってリソースを消費します。

Iainが提案したように、この問題の最も洗練された解決策は、を使用することですDisplay.next_event()。これにより、新しいイベント(キー押下など)が受信されるまで待機するようにプログラムに指示されます。この待機時間の間、プログラムは大量のCPUを消費せず、負荷は劇的に低下するはずです。

于 2012-08-16T15:37:55.820 に答える
4

この回答から以前に投稿された質問取り組むと、pykeyloggerと呼ばれるプログラムの一部であると呼ばれるPythonモジュールpyxhookが明らかになります。

このpyxhookモジュールを使用すると、次のコードで各キーを押すたびにビープ音を鳴らすことができるはずです。

import pyxhook
import time
import os
import sys

def do_beep(event):
    os.system('beep')

hm = pyxhook.HookManager()
hm.HookKeyboard()
hm.KeyDown = do_beep
hm.start()
while True:
    try:
        time.sleep(10)
    except: 
        break
hm.cancel()

beepコマンドがないため、正しくテストできません。ただし、sh: beep: command not foundキーを押すたびにレポートされます。

于 2012-09-19T00:30:32.970 に答える