今回は、何か有用なことを行います。つまり、カルマを表示するアプリケーションを作成します。 表示するだけでなく、すべての「ウィンドウ」の上に、カルマ値と前の値との差があるプレートを表示します。 さらに、プログラムはカルマが上昇すると勝利のゴングを、下降すると絶望の叫びを発表します。 さらに、サーバーとして起動します。つまり、実行中のプログラムのリストには表示されません。
プロセスよりも結果に興味がある人のために、記事の最後にようこそ。 完成したアプリケーションHabraKarma 1.0が見つかります!!!
今回は、プログラムのすべての行についてコメントしません。 私はあなたが少なくともPythonに少し慣れていて、 ドキュメントを読んで、少なくとも私の以前の記事から何かを理解できることを意味します。
仕事の一般原則
プログラム自体は、2つの部分で構成されます。すべての作業を行うサーバー自体と、サーバーの構成、起動、停止を行うGUIです。
サーバー自体は、e32モジュールのstart_server関数によって起動されます。 この関数にはパラメーターが1つだけあります-サーバーとして実行する必要があるPythonスクリプトへのフルパスです。 はい、はい、すべてがとてもシンプルですが、いくつかの制限があります。
サーバーはバックグラウンドで実行されているため、UIを担当するappuifwモジュールを使用できません。 ただし、すべての「ウィンドウ」の上に画像を表示できるtopwindowモジュールを使用して作業の結果を示すため、これも必要ありません。 さらに、globaluiと呼ばれる別のモジュールにアクセスできます。これにより、すべての「ウィンドウ」の上にさまざまな要求、警告、通知などを表示することもできます。これも使用して、サーバーの起動と停止の事実を示します。
別の制限は、アプリケーションフォルダーにあるファイルにアクセスできないことです(x:/ private / UID)。 したがって、さまざまなマルチメディアファイル、設定ファイルを使用する場合、これを中立な場所、たとえばx:/ system / data / AppNameフォルダーに配置する必要があります。 このフォルダには「非表示」属性があるため、そこに配置された写真はギャラリーに表示されず、ライブラリのオーディオファイルに表示されます。
別の問題は、メインプログラムからのサーバーの「分離」です。 つまり、開始することはできますが、実行中かどうかを確認したり、標準モジュールを使用して停止したりすることはできません。 私たちのプログラムでは、次のように進めます。
サーバーは、起動時に、ドライブDのルートにhabra_flagというファイルを作成します。サーバーがシャットダウンすると、このファイルは削除されます。 次に、シェルを実行するときに、探しているファイルが存在するかどうかを確認します。 はいの場合、サーバーが稼働していると見なします。 さらに、サーバーを停止する機能が必要です。 これを行うには、このファイルに何かを書き込みますが、サーバー上でループでチェックします。 ファイルの長さがゼロより大きい場合、作業を停止します。
habra_flagファイルを書き込むドライブDの種類を尋ねられる場合があります。 これは小さなボリュームのRAMディスクで、再起動時にクリアされます。 これを使用して、1石で2羽の鳥を殺します。電話を再起動すると、サーバーが手動で終了し、フラグ付きのファイルが消え、RAMディスク上のファイルシステムのパフォーマンスが向上します。 サーバーとのより複雑な相互作用には、ソケットを使用できます。
UIを書く
プログラムアイコンを「クリック」することで起動されるアプリケーションの面は、 このwiki記事でほぼ完全に説明されているFormクラスになります 。 次のようになります。
そして、ここに私のコメント付きのプログラムコード自体があります:
- #coding:utf-8
- appuifw インポート から *
- e32をインポート
- 輸入 OS
- #設定ファイル、メディアファイルなどが含まれるフォルダー
- data_path = os 。 getcwd ( ) [ 0 ] + u ': \\システム\\データ\\ HabraKarma \\ '
- クラス Main:
- def __init__ ( self ) :
- アプリ。 screen = 'normal'
- #辞書である設定ファイルを読み取り、
- #repr経由で愚かに保存:)
- 自己 。 settings = eval ( open ( data_path + 'set.dat' ) 。 read ( ) )
- #フォームのフィールドのリスト、保存された値をそのフィールドに挿入します。
- 自己 。 フィールド = [
- ( u 'Habrauser' 、 'text' 、 self。settings [ 'user' ] ) 、
- ( u "自動更新(最小)" 、 'number' 、 self。settings [ 'time' ] ) 、
- ( u "サウンドを有効にしますか?" 、 'combo' 、 ( [ u 'Yes' 、u 'No' ] 、 int ( self。settings [ 'sound' ] ) ) )) 、
- ( u "違いを数える" 、 'combo' 、 ( [ u '仕事の始まり' 、u '最後の更新以来' ] 、 int ( self。settings [ 'diff' ] ) ) )) 、
- ( u "Position X" 、 'number' 、 self。settings [ 'X' ] ) 、
- ( u "Position Y" 、 'number' 、 self。settings [ 'Y' ] ) 、
- ]
- #フラグ付きのフォームを作成
- 自己 。 form = Form ( self。fields、flags = FFormDoubleSpaced | FFormEditModeOnly )
- #フォームから値を保存する関数を定義する
- 自己 。 フォーム save_hook = self 保存する
- #サーバーが既に実行されている場合、メニューは「停止」になり、その逆も同様です。
- osの 場合 。 パス 存在する ( u 'd: \\ habra_flag' ) :
- 自己 。 フォーム menu = [ ( u 'Stop' 、 self。stop ) ]
- その他 :
- 自己 。 フォーム menu = [ ( u 'Run' 、 self。start_server ) ]
- #フォームを「実行」します。つまり、画面に表示されるまで
- #そこから抜け出すことはできません。
- 自己 。 フォーム 実行 ( )
- #フォームを終了した後、サーバーが実行されているかどうかを確認し、開始を提案します
- osで ない 場合 。 パス 存在する ( u 'd: \\ habra_flag' ) :
- if query ( u 'Run?' 、 'query' ) :
- 自己 。 start_server ( )
- def start_server ( self ) :
- #実際にサーバー起動機能
- 自己 。 フォーム menu = [ ( u 'Stop' 、 self。stop ) ]
- e32。 start_server ( data_path + 'server.py' )
- def stop ( self ) :
- #サーバー停止機能。
- 自己 。 フォーム menu = [ ( u 'Run' 、 self。start_server ) ]
- open ( u 'd: \\ habra_flag' 、 'w' ) 。 書き込み ( 'stop' )
- def save ( self 、arg = None ) :
- #フォームから値を取得し、設定ファイルに保存します。
- 自己 。 設定 [ 'ユーザー' ] = arg [ 0 ] [ 2 ]
- 自己 。 設定 [ '時間' ] = arg [ 1 ] [ 2 ]
- 自己 。 設定 [ 'サウンド' ] = arg [ 2 ] [ 2 ] [ 1 ]
- 自己 。 設定 [ 'diff' ] = arg [ 3 ] [ 2 ] [ 1 ]
- 自己 。 設定 [ 'X' ] = arg [ 4 ] [ 2 ]
- 自己 。 設定 [ 'Y' ] = arg [ 5 ] [ 2 ]
- open ( data_path + 'set.dat' 、 'w' ) 。 書き込み ( repr ( self。settings ) )
- 真を 返す
- a =メイン( )
サーバーを書くことは残っています:)
- #-*-コーディング:utf-8-*-
- 輸入 OS
- e32をインポート
- インポートシステム
- #エラーをファイルにリダイレクトします。
- sys stderr = open ( 'd: \\ err.txt' 、 'w' )
- globalui を ui として インポート
- topwindowをインポート
- グラフィックのインポート から *
- urllibを インポート する
- オーディオをインポートする
- open ( u 'd: \\ habra_flag' 、 'w' ) 。 書き込み ( '' )
- data_path = os 。 getcwd ( ) [ 0 ] + u ': \\システム\\データ\\ HabraKarma \\ '
- #開始したことを示しています。
- ui。 global_note ( u 'Habrastart!' )
- クラス Habra:
- def __init__ ( self ) :
- #画像を開く
- 自己 。 habr_img =画像。 オープン ( data_path + 'habr.png' )
- 自己 。 update_img =イメージ。 オープン ( data_path + 'update.png' )
- #設定を読む
- 自己 。 settings = eval ( open ( data_path + 'set.dat' ) 。 read ( ) )
- 自己 。 last_karma = eval ( open ( data_path + 'karma.dat' ) 。 read ( ) )
- #オープンサウンド
- 自己 。 bad_sound =オーディオ。 音 オープン ( data_path + 'bad.wav' )
- 自己 。 good_sound =オーディオ。 音 オープン ( data_path + 'good.wav' )
- 自己 。 ループ = True
- #TopWindowウィンドウを作成
- 自己 。 top = topwindow。 TopWindow ( )
- #丸めを示す
- 自己 。 トップ 。 corner_type = 'corner5'
- 自己 。 トップ 。 サイズ = ( 170、35 )
- #設定ファイルから位置を設定
- 自己 。 トップ 。 position = ( self。settings [ 'X' ] 、 self。settings [ 'Y' ] )
- 自己 。 トップ 。 表示 ( )
- 自己 。 karma_screen ( )
- 自己 。 メインループ ( )
- def stop ( self ) :
- 自己 。 ループ = False
- 自己 。 トップ 。 非表示 ( )
- def karma_screen ( self ) :
- #更新するために呼び出される関数
- 自己 。 update_screen ( )
- e32。 ao_sleep ( 0.2 )
- #harba apiで情報を取得
- data = urllib urlopen ( 'http://habrahabr.ru/api/profile/' + self。settings [ 'user' ] ) 。 読む ( )
- #たぶんつまずいたが、これを引っ張りたくない
- #xmlを解析するためのケースライブラリ
- karma = float ( data。split ( '<karma>' ) [ 1 ] 。split ( '</ karma>' ) [ 0 ] )
- #新しいカルマと古いカルマを比較し、
- #状況に応じて、テキストを収集し、色を指定します
- #設定で設定されている場合、サウンドを再生
- 自己の 場合 。 last_karma <カルマ:
- karma_diff = u '(+' + str ( abs ( self。last_karma -karma ) ) + u ')'
- karma_color = 0x009f31
- 自己で なければ 。 設定 [ 'サウンド' ] :
- 自己 。 good_sound プレイ ( )
- エリフセルフ 。 last_karma >カルマ:
- karma_diff = u '(-' + str ( abs ( self。last_karma -karma ) ) + u ')'
- karma_color = 0xc30202
- 自己で なければ 。 設定 [ 'サウンド' ] :
- 自己 。 bad_sound 。 プレイ ( )
- その他 :
- karma_diff = u ''
- karma_color = 0xffffff
- 自己の 場合 。 設定 [ 'diff' ] :
- 自己 。 last_karma =カルマ
- open ( data_path + 'karma.dat' 、 'w' ) 。 書き込み ( repr ( karma ) )
- #ここで、幅のピクセル数がテキストを占めることがわかります
- karma_width = self img 。 measure_text ( unicode ( karma ) ) [ 0 ] [ 2 ]
- diff_width = self img 。 measure_text ( karma_diff ) [ 0 ] [ 2 ]
- #そして技術の問題:)
- 自己 。 img =イメージ。 新規 ( ( 45 + karma_width + diff_width、 35 ) )
- 自己 。 トップ 。 size = ( self。img。size [ 0 ] 、 35 )
- 自己 。 img 。 テキスト ( ( 35、25 ) 、 ユニコード ( karma ) )
- 自己 。 img 。 テキスト ( ( 35 + karma_width + 5、25 ) 、karma_diff、fill = karma_color )
- 自己 。 img 。 blit ( self。habr_img )
- 自己 。 トップ 。 add_image ( self。img 、 ( 0、0 ) )
- def update_screen ( self ) :
- #これは更新中に表示されます
- 自己 。 img =イメージ。 新規 ( ( 165、35 ) )
- 自己 。 トップ 。 size = ( self。img。size [ 0 ] 、 35 )
- 自己 。 img 。 blit ( self。update_img )
- 自己 。 img 。 テキスト ( ( 35、25 ) 、u '更新済み' )
- 自己 。 トップ 。 add_image ( self。img 、 ( 0、0 ) )
- def mainloop ( self ) :
- #そしてメインサーバーループを開始
- interval = self 設定 [ '時間' ] * 60
- カウント= 0
- 自己 ながら 。 ループ :
- #注文された場合、サーバーを停止
- 開いている 場合 ( u 'd: \\ habra_flag' ) 。 読み取り ( ) :
- os 。 削除 ( u 'd: \\ habra_flag' )
- ui。 global_note ( u 'Habrastop!' )
- 自己 。 ループ = False
- カウント+ = 1
- #時間が来たら、カルマを公開します。
- カウント>間隔の場合 :
- カウント= 0
- 自己 。 karma_screen ( )
- e32。 ao_sleep ( 1 )
- habr = Habra ( )
sisですべてを収集し、カルマを見ることが残っています:)
ソースは、写真、音声、アイコンと一緒にここから撮影できます。 シンボルのアセンブリオプションで、次のように記述します。
--extrasdir =データ--lang = RU --icon = icon_path
そして結果を取ります...
したがって、symbain 9.xのHabraKarmaアプリケーションを紹介します
アプリケーションをインストールし、ユーザー名を入力し、更新時間、ウィンドウの位置を設定します。 これでサーバーを起動でき、すべてのウィンドウの上部にカルマが表示されます。 その後、プログラムを閉じることができます。プログラムを再度入力してオフにするまで、ウィンドウは残ります。
こちらからダウンロード(sis、56 kb、署名不要)
動作するには、バージョン1.9.7以上のPythonランタイムが必要であることを忘れないでください( ダウンロード )。
Pythonとプログラムを同じドライブに入れてください!