【wxPython】アプリケーションオブジェクトの作成

Appオブジェクトはアプリケーションの初期化を行います。
すべてのwxPythonアプリケーションには、Appオブジェクトが一つ存在しなければなりません。
また、他のどんなGUIオブジェクトよりも前にインスタンス化されている必要があります。
以下のコードが、すべてのwxPythonアプリケーションの基本となります。
Hello Worldっぽいアプリケーションです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx


class MyApp(wx.App):
    def OnInit(self):
        wx.MessageBox("Hello wxPython", "wxApp")
        return True

if __name__ == '__main__':
    app = MyApp(False)
    app.MainLoop()

このスクリプトを実行すると、以下のようなメッセージボックスが表示されます。
f:id:hiron_tn:20140720220721p:plain

同じことをやるだけなら、以下のコードでもできます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx

app = wx.App()
wx.MessageBox("Hello wxPython", "wxApp")
app.MainLoop()

どのように動くか

アプリケーションオブジェクトが作られたときに、OnInitメソッドが呼ばれます。
OnInitには、インスタンス生成の際にwx.Appのinitに加えたい操作を書きます。
このメソッドはオーバライドされ、アプリケーションを初期化するためのエントリーポイントとして使われます。
OnInitは引数を取らず、ブール値を返します。ブール値がFalseだとプログラムは即終了してしまいます。

この例では、MyAppの引数としてFalseを渡してAppオブジェクトを作りました。
この引数はwxPythonに出力をリダイレクトするか否かを教えるために使われます。

Appオブジェクトを作り、初期化が完了したら、あとはイベントループを始めるためにMainLoopメソッドを呼ぶだけです。
このメソッドはアプリケーションが生きている間に起こるすべてのイベントを受け取り、処理します。

さらなる詳細

wx.Appクラスのコンストラクタは、4つのオプションのキーワード引数を取ります。
wx.App(redirect=True, filename=None, useBestVisual=False, clearSigInt=True)

4つのオプションのキーワード引数は以下の通りです:
・redirect:標準出力をリダイレクト
・filename:リダイレクトがTrueのとき、リダイレクト先の出力ファイルを指定するために使われる
・useBestVisual:アプリケーションが最高のビジュアルを使用するかを指定する
・clearSigInt:これをTrueにセットすると、アプリケーションはCtrl+Cを押すことで終了できるようになる

Pythonでソケットタイムアウト値の設定と取得

コードは以下の通り:

#!/usr/bin/env python
#  -*- coding: utf-8 -*-

import socket


def test_socket_timeout():
    """
    タイムアウト値を設定する
    """
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print "Default socket timeout: %s" % s.gettimeout()
    s.settimeout(100)
    print "Current socket timeout: %s" % s.gettimeout()


if __name__ == '__main__':
    test_socket_timeout()

gettimeout()はデフォルトのタイムアウト値を取得する。
settimeout()は特定のタイムアウト値を設定する。

Pythonでホストバイトオーダとネットワークバイトオーダ間の変換をする

低レベルネットワークのアプリケーションを書くときに、2つのマシン間での低レベルデータ伝送をすることがある。
このときデータを、ホストの形式からネットワーク形式へ変換する必要がある。

コードは以下の通り:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket


def convert_integer(data):
    """
    バイトオーダを変換する
    """
    print "Original: %s" % data
    # 32ビット
    print "Long  host byte order: %s, Network byte order: %s" % (socket.ntohl(data), socket.htonl(data))
    # 16ビット
    print "Short  host byte order: %s, Network byte order: %s" % (socket.ntohs(data), socket.htons(data))


if __name__ == '__main__':
    convert_integer(data=12345)

ntohl()は、32bitの正の整数のバイトオーダをネットワークバイトオーダからホストバイトオーダに変換する。
htonl()は、32ビットの正の整数のバイトオーダを、ホストバイトオーダからネットワークバイトオーダに変換する。
ntohs()は、16ビットの正の整数のバイトオーダを、ネットワークバイトオーダからホストバイトオーダに変換する。
htons()は、16ビットの正の整数のバイトオーダを、ホストバイトオーダからネットワークバイトオーダに変換する。

Pythonでポート番号とプロトコル名からサービス名を調べる

コードは以下の通り:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket


def find_service_name(port, protocolname):
    """
    ポート番号とプロトコル名からサービス名を調べる
    """
    print "Port: %s => service name: %s" % (port, socket.getservbyport(port, protocolname))


if __name__ == '__main__':
    find_service_name(port=80, protocolname='tcp')
    find_service_name(port=25, protocolname='tcp')
    find_service_name(port=53, protocolname=‘udp')

getservbyport()にポート番号とプロトコル名を与えると、サービス名を返してくれる。

PythonでIPv4アドレスを別の形式に変換する

PythonIPv4アドレスを別の形式に変換する
低レベルネットワーク機能を扱いたいときに、IPアドレスを普通の文字列で表記すると扱いにくい。
そこで、パックされた32bitバイナリ形式に変換する。

コードは以下の通り:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
from binascii import hexlify


def convert_ip4_address(ip_address):
    """
    パックしたIPアドレスと元のアドレスを表示する
    """
    packed_ip_addr = socket.inet_aton(ip_address)
    unpacked_ip_addr = socket.inet_ntoa(packed_ip_addr)
    print "Packed: %s, Unpacked: %s" % (hexlify(packed_ip_addr), unpacked_ip_addr)


if __name__ == '__main__':
    convert_ip4_address(ip_address='127.0.0.1')

inet_aton(ip_string)は、IPv4アドレスを32bitにパックしたバイナリ形式に変換し、長さ4の文字列として返す。
inet_ntoa(packed_ip)は、32bitにパックしたバイナリ形式のIPv4アドレスをドット記法による文字列(‘127.0.0.1’など)に変換する。
hexlify()はバイナリデータを16進数表記へ変換する。

PythonでリモートホストのIPアドレスを調べる

コードは以下の通り:

#!/usr/bin/env python
#  -*- coding: utf-8 -*-

import socket


def print_remote_machine_info(remote_host):
    """
    リモートのIPアドレスを表示する
    """
    try:
        print "IP address: %s" % socket.gethostbyname(remote_host)
    except socket.error, err_msg:
        print "%s: %s" % (remote_host, err_msg)


if __name__ == '__main__':
    print_remote_machine_info(remote_host='www.google.co.jp')

gethostbyname()でホスト名を解決できなかったときは、例外処理を行う。

Pythonでローカルのホスト名とIPv4アドレスを確認する

コードは以下の通り:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket


def print_local_machine_info():
    """
    ローカルのホスト名とIPアドレスを表示する
    """
    host_name = socket.gethostname()
    ip_address = socket.gethostbyname(host_name)
    print "Host name : %s" % host_name
    print "IP address : %s" % ip_address

if __name__ == '__main__':
    print_local_machine_info()

gethostname()はホスト名を返すメソッド
gethostbyname(host_name)はホスト名を引数に取り、そのIPv4アドレスを返すメソッド