リンク

2017年6月29日木曜日

pythonでGUIツールを作る 〜ToasterBox(トースターボックス)〜


今回は、ボタンを押すと下からニュッと飛び出してくるメッセージ系ウィジット「ToasterBox」をご紹介します。

「ToasterBox」はその名の通り、焼けたトーストが「チンっ」と飛び出てくることに由来しています。(大嘘)


面白そうなウィジットですよね!


環境
  • macOS Sierra 10.12.5
  • python 3.4
  • wxPython 4.0.0a3


スクリプト
# -*- coding: UTF-8 -*-

import wx
import wx.lib.agw.toasterbox as TB

class App(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(200, 200))

        p = wx.Panel(self, wx.ID_ANY)

        b = wx.Button(p, wx.ID_ANY, 'ボタン')
        b.Bind(wx.EVT_BUTTON, self.click)

        # レイアウト
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(b, flag=wx.ALL, border=10)
        p.SetSizer(layout)

        self.Show()

    def click(self, event):
        # マウス座標を取得
        (x, y) = wx.GetMousePosition()

        # ToasterBox
        toaster = TB.ToasterBox(self, tbstyle=TB.TB_SIMPLE)
        toaster.SetPopupBackgroundColour("pink")
        toaster.SetPopupPauseTime(3000)
        toaster.SetPopupText("見てくれて\nありがとう") 
        toaster.SetPopupSize(wx.Size(80, 80))
        toaster.SetPopupPosition(wx.Position(x + 10, y + 10))
        toaster.SetPopupTextFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, 'メイリオ'))

        toaster.Play()


if __name__ == "__main__":
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()


実行結果
いつもありがとうございます。



解説
トースターボックスを使用するには、wx.lib.agwパッケージのtoasterboxクラスをインポートします。
今回は簡略化するため、asを用いて「TB」としました。
import wx.lib.agw.toasterbox as TB

続いてインスタンス化です。
今回はボタンがクリックされた時にインスタンス化を行うようになっています。
toaster = TB.ToasterBox(self, tbstyle=TB.TB_SIMPLE)
この部分でインスタンス化を行なっています。
この時の引数は(親ウィジット、TBスタイル)です。

TBスタイルは次の2種類から選択できます。
  • TB_SIMPLE
  • TB_COMPLEX
TB_SIMPLEは背景画像やテキストを指定することができます。
TB_COMPLEXはAddPanelメソッドを使用することでToasterBox内にパネルを設置することができ、ボタンなどのウィジットを追加することができます。

tbstyle比較

今回は省略していますが、他にも「windowstyle」「closingstyle」「scrollType」を指定することができます。

windowstyle
windowstyleはトースターボックスの外観に関するスタイルで、次の2つがあります。
  • TB_DEFAULT_STYLE
  • TB_CAPTION
TB_DEFAULT_STYLEは上の画像のように周りに何もない状態です。
TB_CAPTIONはフレームやダイアログのように周りに枠があり、タイトルや×ボタンが表示されます。

windowstyle比較

closingstyle
closingstyleはトースターボックスを閉じるタイミングに関するスタイルで、次の2つがあります。
  • TB_ONTIME
  • TB_ONCLICK
TB_ONTIMEは指定時間が経過するまで表示されます。
TB_ONCLICKは指定時間の経過を待たずとも、枠内をクリックすると閉じることができます。


scrollType
scrollTypeはトースターボックスの表示方法に関するスタイルで、次の3つがあります。
  • TB_SCR_TYPE_DU
  • TB_SCR_TYPE_UD
  • TB_SCR_TYPE_FADE
TB_SCR_TYPE_DUは下から上へ、TB_SCR_TYPE_UDは上から下へ、TB_SCR_TYPE_FADEはジワーと出てきて、ジワーと消えます。



メソッド紹介
使用頻度が高そうなメソッドを厳選してご紹介します。
# テキストを設定する(tbstyleがTB_SIMPLEの時のみ)
toaster.SetPopupText("見てくれて\nありがとう") 

# 背景色を設定する(tbstyleがTB_SIMPLEの時のみ)
toaster.SetPopupBackgroundColour("pink")

# 画像を設定する(tbstyleがTB_SIMPLEの時のみ)
toaster.SetPopupBitmap(wx.Bitmap("image.png"))

# 表示時間をミリ秒で設定する
toaster.SetPopupPauseTime(3000)

# 表示位置を設定する(左上角の位置)
toaster.SetPopupPosition(wx.Position(10, 10))

# サイズを設定する
toaster.SetPopupSize(wx.Size(80, 80))

# タイトルを設定する
toaster.SetTitle("タイトル")


参考
・公式リファレンス:wx.lib.agw.toasterbox.ToasterBox


まとめ
トースターボックスはよく使われるダイアログとは一味違っていて、動きがあるぶん、作る側も使う側も楽しめるようなウィジットです。

ボタンやテキストコントロールの設置も可能ですので、アイデア次第で色々と活躍してくれるかもしれません。


pythonでGUIツールを作る 〜SuperToolTip(スーパーツールチップ)〜


今回は「ヘッダー部分」「本文」「フッター部分」の3つを指定することができるツールチップをご紹介します。

ツールチップとは、特定のウィジットにマウスカーソルを合わせた時に、数秒間だけ表示されるメッセージのことです。

通常のツールチップはただ文字列を表示するだけですが、スーパーツールチップは、上に書いたように、3箇所に分けて情報を表示することができ、かつ、それぞれの部分に異なる色を設定し、グラデーションにすることもできます。
さらに、3箇所それぞれに画像を表示させるなど、まさにスーパーな機能がついたツールチップです。

通常のツールチップ



環境
  • macOS Sierra 10.12.5
  • python 3.4
  • wxPython 4.0.0a3


スクリプト
# -*- coding: UTF-8 -*-

import wx
import wx.lib.agw.supertooltip as STT

class App(wx.Frame):
    """ GUI """
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 200))

        p = wx.Panel(self, wx.ID_ANY)

        button = wx.Button(p, wx.ID_ANY, "ボタン", pos=(100, 50))

        tip = STT.SuperToolTip(message="素敵なメッセージ\n", header='へっだーぶぶん', footer='ふったーぶぶん')
        tip.SetTarget(button)  # ターゲット
        tip.SetDrawHeaderLine(True)  # ヘッダー部の仕切り線:あり
        tip.SetDrawFooterLine(True)  # フッター部の仕切り線:あり
        tip.SetMiddleGradientColour("yellow")
        tip.SetTopGradientColour("green")
        tip.SetBottomGradientColour("red")
        tip.SetBodyImage(wx.Bitmap("icon.png"))

        # レイアウト
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(button, flag=wx.ALL, border=10)
        p.SetSizer(layout)

        self.Show()


if __name__ == "__main__":
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()


実行結果
 ボタンにマウスを合わせるとスーパーツールチップが表示されます。



解説
スーパーツールチップを使用するには、wx.lib.agwパッケージのsurpertooltipクラスをインポートします。
今回は簡略化するため、asを用いて「STT」としました。
import wx.lib.agw.supertooltip as STT

続いてインスタンス化です。
tip = STT.SuperToolTip(message="素敵なメッセージ\n", header='へっだーぶぶん', footer='ふったーぶぶん')
この部分でインスタンス化を行なっています。
この時の引数は(メッセージテキスト、ヘッダーテキスト、フッターテキスト)です。
フッターテキストは省略することもできます。


メソッド紹介
スーパーツールチップで使用頻度が高そうなメソッドを厳選してご紹介します。
# ヘッダー部の仕切り線を有効にする
tip.SetDrawHeaderLine(True)

# フッター部の仕切り線を有効にする
tip.SetDrawFooterLine(True)

# ヘッダーテキストを設定する
tip.SetHeader("新しいテキスト")

# メッセージを設定する
tip.SetMessage("新しい本文")

# フッターテキストを設定する
tip.SetFooter("新しいテキスト")

# ターゲットを設定する
tip.SetTarget(button)

# ヘッダー部分の色を指定する
tip.SetTopGradientColour("green")

# メッセージ部分の色を指定する
tip.SetMiddleGradientColour("red")

# フッター部分の色を指定する
tip.SetBottomGradientColour("yellow")

# ヘッダー部分に表示するイメージを指定する
tip.SetHeaderBitmap(wx.Bitmap("icon.png"))

# メッセージ部分に表示するイメージを指定する
tip.SetBodyImage(wx.Bitmap("icon.png"))

# フッター部分に表示するイメージを指定する
tip.SetFooterBitmap(wx.Bitmap("icon.png"))

# # # # # # # # # # # # # # # # # # # # # # # # # 

# ヘッダーテキストを取得する
tip.GetHeader()

# メッセージを取得する
tip.GetMessage()

# フッターテキストを取得する
tip.GetFooter()

# ターゲットを取得する
tip.GetTarget()

# ヘッダー部分の色を取得する
tip.GetTopGradientColour()

# メッセージ部分の色を取得する
tip.GetMiddleGradientColour()

# フッター部分の色を取得する
tip.GetBottomGradientColour()

# ヘッダー部分のイメージを取得する
tip.GetHeaderBitmap()

# メッセージ部分のイメージを取得する
tip.GetBodyImage()

# フッター部分のイメージを取得する
tip.GetFooterBitmap()


参考
・公式リファレンス:wx.lib.agw.supertooltip.SuperToolTip


まとめ
スーパーツールチップは自由度のかなり高いツールチップです。
できることが多いため、ついつい情報量が多くなりすぎてしまうこともあります。
「ツールチップは補助的な役割」ということを忘れずに、適切な内容にすることを心がけましょう。


pythonでGUIツールを作る 〜SpinCtrlDouble(スピンコントロールダブル)〜


今回は、SpinCtrlに似たウィジット「SpinCtrlDouble」をご紹介します。

以前ご紹介したSpinCtrlは数値のみが入力可能で、値を上下させるボタンが初期配置されている便利なものでした。
今回の「SpinCtrlDouble」は基本的には「SpinCtrl」と同様ですが、”小数点も使える”という点が異なっています。


環境
  • macOS Sierra 10.12.5
  • python 3.4
  • wxPython 4.0.0a3


スクリプト
# -*- coding: UTF-8 -*-

import wx

class App(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 300), style=wx.DEFAULT_FRAME_STYLE)

        p = wx.Panel(self, wx.ID_ANY)

        # SpinCtrl
        self.spinS = wx.SpinCtrl(p, wx.ID_ANY, size=(100, 25))

        # SpinCtrlDouble
        self.spinD = wx.SpinCtrlDouble(p, wx.ID_ANY, '0', inc=0.01, size=(100, 25))

        b = wx.Button(p, wx.ID_ANY, 'button')
        b.Bind(wx.EVT_BUTTON, self.click)

        self.text = wx.StaticText(p, wx.ID_ANY, 'クリック時の値')

        # レイアウト
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(self.spinS, flag=wx.ALL, border=10)
        layout.Add(self.spinD, flag=wx.ALL, border=10)
        layout.Add(b, flag=wx.ALL, border=10)
        layout.Add(self.text, flag=wx.ALL, border=10)

        p.SetSizer(layout)

        self.Show()

    def click(self, event):
        self.text.SetLabel(str(self.spinD.GetValue()))


if __name__ == "__main__":
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()


実行結果
実行直後は違いがわかりませんが、上が「SpinCtrl」で下が「SpinCtrlDouble」です。


動かしているところ。


解説
# SpinCtrlDouble
self.spinD = wx.SpinCtrlDouble(p, wx.ID_ANY, '0', inc=0.01, size=(100, 25))
ここでインスタンス化を行なっています。
この時の引数は(親ウィジット、ID、初期値、インクリメント値、サイズ)です。

インクリメントというのは「増加」という意味ですが、ここでは「1クリックごとの増減値」を意味する言葉として使用しています。
今回はインクリメント値に「0.01」を指定していますので、上下のボタンをクリックするたびに現在の値から0.01ずつ増減します。


メソッド紹介
基本的にはSpinCtrlと同様のメソッドを使用することができます。
# 現在値を取得する
self.spinD.GetValue()

# 設定されている最小値を取得する
self.spinD.GetMin()

# 設定されている最大値を取得する
self.spinD.GetMax()

# 設定されている最小値と最大値を取得する
self.spinD.GetRange()

# 設定されているインクリメント値を取得する
self.spinD.GetIncrement()

# 値を設定する
self.spinD.SetValue(0.2)

# 最小値を設定する
self.spinD.SetMin(0.2)

# 最大値を設定する
self.spinD.SetMax(50.0)

# 最小値と最大値を設定する
self.spinD.SetRange(10.0, 50.0)

# インクリメント値を設定する
self.spinD.SetIncrement(0.03)


まとめ
「SpinCtrl」「SpinCtrlDouble」はどちらもユーザーに数値のみの入力を強制させるためのウィジットです。
通常の使用であれば「SpinCtrl」で十分だとは思いますが、必ず小数点で入力しなければいけないような場面では「SpinCtrlDouble」を使うようにしましょう。


pythonでGUIツールを作る 〜CubeColourDialog(キューブカラーダイアログ)〜


今回はwxPythonで使える数あるウィジットの中から、「CubeColourDialog」をご紹介します。

早速見てください!
どうですか?カッコよくないですか?!
これが最初から用意されているっていうんですから驚きです。
(画像はmacOSで取得したものを使用していますが、Windowsでも使用できます)



一般的な用途であれば「ColourDialog」で十分なんですけどね。

wx.ColourDialog(macOS X)

環境
  • macOS Sierra 10.12.5
  • python 3.4
  • wxPython 4.0.0a3

スクリプト
# -*- coding: UTF-8 -*-

import wx
import wx.lib.agw.cubecolourdialog as cc

class App(wx.Frame):
    
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 300))

        p = wx.Panel(self, wx.ID_ANY)

        b = wx.Button(p, wx.ID_ANY, 'ボタン')
        b.Bind(wx.EVT_BUTTON, self.click)

        # レイアウト
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(b)
        p.SetSizer(layout)

        self.Show()

    def click(self, event):
        """ event """
        d = cc.CubeColourDialog(self)
        d.ShowModal()
        d.Destroy()


if __name__ == "__main__":
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()


実行結果


解説
CubeColourDialogを使用するにはwx.lib.agwパッケージのcubecolourdialogクラスをインポートします。
今回は簡略化するため、asを用いて「cc」としました。
import wx.lib.agw.cubecolourdialog as cc

続いてインスタンス化です。
今回は、ボタンをクリックした時にインスタンス化するようになっています。
d = cc.CubeColourDialog(self)
引数は(親ウィジット)です。
wx.ColourDataを引数に持たせることもできるようですが、今回は省略しています。


メソッド紹介
# HSB値を取得
d.GetHSVAColour()
>> (0, 0, 128, 255)

# RGB値を取得
d.GetRGBAColour()
>> (128, 128, 128, 255)


参考
・公式リファレンス:wx.lib.agw.cubecolourdialog.CubeColourDialog


まとめ
上にも書きましたが、通常使用であれば、「wx.ColourDialog」で十分だと思います。
しかし、今回ご紹介した「CubeColourDialog」は見た目も華やかで、Cubeの部分がリンクしながら動くところがなんとも男心をくすぐります。
興味が湧いた方は是非一度使ってみてくださいね。

2017年6月28日水曜日

pythonでGUIツールを作る 〜AquaButton(アクアボタン)〜


今回は、wxPythonで使える、ちょっと変わったボタン・ウィジットをご紹介します。

ご紹介するのは「アクアボタン」というもので、通常のボタンと比べると見た目から全然違います。


少し見にくいですが、上のボタンが「アクアボタン」、下のボタンが「通常のボタン」です。
アクアボタンの特徴は、「影があり、浮いているように見える」ことです。


環境
  • macOS Sierra 10.12.5
  • python 3.4
  • wxPython 4.0.0a3

スクリプト
# -*- coding: UTF-8 -*-

import wx
import wx.lib.agw.aquabutton as aq

class App(wx.Frame):
    """ GUI """
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 300))
        p = wx.Panel(self, wx.ID_ANY)

        # アクアボタン
        button = aq.AquaButton(p, wx.ID_ANY, None, 'アクアボタン')
        button.Bind(wx.EVT_BUTTON, self.click)

        # 通常のボタン
        b = wx.Button(p, wx.ID_ANY, '通常のボタン')

        # レイアウト
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(button, flag=wx.ALL, border=20)
        layout.Add(b, flag=wx.ALL, border=20)
        p.SetSizer(layout)

        self.Show()

    def click(self, event):
        """ クリックイベント """
        print('click')


if __name__ == "__main__":
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()


解説
アクアボタンを使用するにはwx.lib.agwパッケージのaquabuttonクラスをインポートします。
今回は簡略化するため、asを用いて「aq」としました。
import wx.lib.agw.aquabutton as aq

続いてインスタンス化です。
# アクアボタン
button = aq.AquaButton(p, wx.ID_ANY, None, 'アクアボタン')
この部分でインスタンス化を行なっています。
引数は(親ウィジット、ID、イメージ、文字列)です。


メソッド紹介
アクアボタンは見た目が違うだけで、基本的には通常のボタンと同様のメソッドを使うことができます。
ここでは、アクアボタン特有のメソッドをご紹介します。

# 影部分の色を指定する (macOSでは反映されない)
button.SetShadowColour("red")

# ボタン上にマウスカーソルがあるときの色を指定する
button.SetHoverColour("blue")

# ボタンの後ろ部分四角の色を指定する
button.SetRectColour("green")

# ボタンにフォーカスがあるときの色を指定する
button.SetFocusColour("red")

ボタンの文字色を指定、マウスオーバー時の色を指定、後ろ部分の色を指定した場合はこのようになります。

まとめ
アクアボタンは見た目を一風変わったものにしながらも、操作性は通常のボタンと変わらないため、あっさりと導入することができます。

デザイン重視のアプリケーションを作成しようとされている方は、一度検討してみてはいかがでしょうか。

wxPythonでホットキーを使う


今回は、wxPythonでホットキーを使う方法をご紹介します。
ホットキーはショートカットキーとも呼ばれるもので、特定のキー入力に指定の処理などを関連づけるものです。

Windowsで言えば、[Ctrl] + [c]のコピー、  [Ctrl] + [v]の貼り付けが有名ですね。

wxPythonでは、以前ご紹介したwx.Menubarにショートカットキーを設定する方法はよく紹介されていますが、今回の記事はそれとは違い、メニューバーは関係なく、アプリケーションにホットキーを設定します。

例えば、「アプリケーションを起動中に[Ctrl] + [z]を入力すると、メッセージボックスが表示される」というような動作を実現します。


環境
  • macOS Sierra 10.12.5
  • python 3.4
  • wxPython 4.0.0a3


スクリプト
# -*- coding: UTF-8 -*-

import wx

class App(wx.Frame):
    """ GUI """
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 300))

        # キーの設定
        self.RegisterHotKey(1234, wx.MOD_ALT, ord('z'))  # Windows向け
        #self.RegisterHotKey(1234, wx.MOD_CMD, ord('z'))  # macOS X向け

        # ホットキーイベントハンドラ
        self.Bind(wx.EVT_HOTKEY, self.callhotkey)

        p = wx.Panel(self, wx.ID_ANY)
        l = wx.StaticText(p, wx.ID_ANY, 'ホットキーのテスト')
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(l, flag=wx.ALL, border=10)
        p.SetSizer(layout)

        self.Show()

    def callhotkey(self, event):
        """ ホットキーイベント """
        dialog = wx.MessageDialog(self,'ホットキーを検知しました', '検知')
        dialog.ShowModal() 
        dialog.Destroy() 


if __name__ == "__main__":
    app = wx.App()
    App(None, wx.ID_ANY, 'ホットキー')
    app.MainLoop()


実行結果
設定したホットキーを入力するとメッセージボックスが表示されます。



解説
ホットキーを設定するには、Frameに対してRegisterHotKeyメソッドを指定します。
さらに、ホットキーが入力された時のイベントハンドラを指定しておきます。
# キーの設定
self.RegisterHotKey(1234, wx.MOD_ALT, ord('z'))  # Windows向け

# ホットキーイベントハンドラ
self.Bind(wx.EVT_HOTKEY, self.callhotkey)
引数は(ホットキーID、修飾キー、仮想キー)です。

ホットキーIDは任意の数値でOKです。

修飾キーは必須で、次の中から指定します。
  • wx.MOD_ALT    : Altキー   (Windowsのみ対応)
  • wx.MOD_CONTROL : Ctrlキー   (Windowsのみ対応)
  • wx.MOD_SHIFT   : Shiftキー   (両対応)
  • wx.MOD_WIN     : Windowsキー (Windowsのみ対応)
  • wx.MOD_CMD    : commandキー (macOSのみ対応)

仮装キーはキーコード(数値)で指定する、wx.KeyCodeで指定する、ordで指定する、などの方法があります。

1.キーコード(数値)で指定する方法
それぞれのキーにはキーコードが設定されています。
(Windowsの)Enterキーは13、スペースキーは32といった具合です。

参考:Windows→キーコード一覧
参考:macOS →キーコード一覧
  
<例>
# Altキー + zキー
self.RegisterHotKey(1234, wx.MOD_ALT, 90)  # Windows向け

2.wx.KeyCodeで指定する
wxPythonであらかじめ定義してある定数名で指定する方法です。
ただし、通常キー(Aキーや数字キー)は未定義のようです。
詳細はwx.KeyCodeをご覧ください。

<例>
# Altキー + ↑キー
self.RegisterHotKey(1234, wx.MOD_ALT, wx.WXK_UP)  # Windows向け

3.ordで指定する
ord関数は指定した文字列のASCIIコードを返します。
アルファベットと数値は、キーコードとASCIIコードが大体同じ(例外もある)なので、わざわざキーコードを調べなくてもホットキーを設定することができます。

<例>
# Altキー + zキー
self.RegisterHotKey(1234, wx.MOD_ALT, ord('z'))  # Windows向け


おまけ
設定しているホットキーを解除するには次のように記述します。
# ホットキー解除
self.UnregisterHotKey(1234)
引数は(ホットキーID)です。


まとめ
メニューバーで使用されるショートカットキーはアプリケーションがアクティブ状態でないと動作しませんが、今回ご紹介したホットキーは、非アクティブであっても動作します。

例えば「アプリケーション実行時はFrameをShow()せず、ホットキーが入力された時にShow()する」というような使い方も可能です。
 タスクトレイ常駐型のアプリケーションなんかと相性が良さそうですね。

pythonからYahoo! JAPAN Web APIサービスを利用する


みなさん、Web APIサービス使ってますか?!
楽天やらAmazonやらいろんなところがAPIを公開していますよね!

今回は数あるWeb APIサービスの中からYahoo! JAPAN テキスト解析APIの「ルビ振り」をpythonから使ってみます。
(インターネット環境は必須です)


環境
  • macOS Sierra 10.12.5
  • python 3.4


前準備1 Yahoo! JAPAN IDの取得
Yahoo! JAPANのWeb APIを使用するためには当然のごとく「Yahoo! JAPAN ID」が必要です。
すでにお持ちの方は次の「前準備2 アプリケーションIDの取得」に進んでください。
まだお持ちでない方はこちらからYahoo! JAPAN IDを取得してください。


前準備2 アプリケーションIDの取得
Yahoo! JAPAN Web APIを利用するために、「アプリケーションID」を取得します。
こちらにアクセスし、新たにアプリケーションIDを取得してください。

取得方法は下記のヘルプページに詳しく掲載されています。
ヘルプ:アプリケーションIDを登録する


モジュールのインストール
今回使用するのは「urllibモジュール」だけです。
標準モジュールなので、意識して削除していない限り、インストール作業は必要ありません。


スクリプト
# -*- coding: UTF-8 -*-

from urllib import request, parse

def yahoo_api(text):
    """ リクエスト """

    # Yahoo! JAPAN テキスト解析WebAPI ルビ振りのURL
    url = 'https://jlp.yahooapis.jp/FuriganaService/V1/furigana'

    # アプリケーションID
    appid = 'ここを取得したアプリケーションIDに置き換えてください'

    # 変換する文字列の文字コード変換
    sentence = parse.quote(text.encode('utf-8'))

    # URLを構成
    target = "%s?appid=%s&sentence=%s" % (url, appid, sentence)

    # ルビ振りサービスへアクセス&返り値を取得
    response = request.urlopen(target).read()
    return response

if __name__ == "__main__":

    # 対象の文字列
    target = '人生楽ありゃ苦もあるさ'

    # リクエストの実行
    api = yahoo_api(target)

    print(api.decode('utf-8'))


pythonで画像からQRコードを読み込む


今回は、pythonを使って画像ファイル内のQRコード内容を取得する方法をご紹介します。

環境
  • macOS Sierra 10.12.5
  • python 3.4


モジュールのインストール
今回使用するのは「pyzbarモジュール」です。
python2系では「zbarモジュール」が使えるのですが、3系には対応していません。
なので「pyzbarモジュール」を使用します。

Windowsの方はコマンドプロンプト、Macの方はターミナルを起動し、次のコマンドを実行してください。
>> pip install pyzbar
もしくは下記のページからソースを直接ダウンロードしてください。
https://pypi.python.org/pypi/pyzbar/

pyzbarモジュールだけでなく「PILモジュール」も必要です。
未入手の方は次のコマンドで合わせて入手してください。
>> pip install pillow

さらに、大元となる「ZBar」も必要です。
下記のページにアクセスし、別途ダウンロードを行なってください。
http://zbar.sourceforge.net/
Macの方はHomebrewが使える状態であれば、次のコマンドでもダウンロード&インストールが完了しますので楽チンです。
>> brew install zbar

以上で環境の構築は完了です。


使用する画像
今回はpythonでQRコード画像を作成するで作成した画像ファイルを使用します。


スクリプト
pythonスクリプトファイルと同じフォルダ内にある「test.png」にアクセスし、その中のQRコード内容を出力するサンプルです。
# -*- coding: UTF-8 -*-

from pyzbar.pyzbar import decode
from PIL import Image

# 画像ファイルの指定
image = "test.png"

# QRコードの読取り
data = decode(Image.open(image))

# コード内容を出力
print(data[0][0].decode('utf-8', 'ignore'))



2017年6月27日火曜日

pythonでQRコード画像を作成する

今回は、pythonを使ってQRコードを作成する方法をご紹介します。

環境
  • macOS Sierra 10.12.5
  • python 3.4

モジュールのインストール
今回使用するのは「PyQRCodeモジュール」です。
Windowsの方はコマンドプロンプト、Macの方はターミナルを起動し、次のコマンドを実行してください。
>> pip install pyqrcode

pipが使用できない場合は以下よりソースファイルを取得し、中のsetup.pyを実行してください。
https://pypi.python.org/pypi/PyQRCode

また、ご利用の環境によっては「pypngモジュール」を別途インストールする必要があります。
>> pip install pypng
もしくは
https://pypi.python.org/pypi/pypng

モジュールの用意が整っている前提で進めます。


基本スクリプト
# -*- coding: UTF-8 -*-

import pyqrcode

a = pyqrcode.create(content='本日は晴天ナリよ')
a.png(file='test.png')

実行結果
pythonスクリプトと同じフォルダ内にtest.pngができます。
とても小さい画像になってしまいました。
これはQRコードの内容が非常に少ないからです。
内容に比例して画像サイズも大きくなります。


pythonでXMLファイルを操作する

今回はpythonからXMLファイルを開き、情報を取得&編集する方法をご紹介します。

環境
  • macOS Sierra 10.12.5
  • python 3.4

    モジュールのインストール
    今回使用するのは「xmlモジュール」です。
    これは標準モジュールなので、意識して削除していない限りインストールせずに使用することができます。


    XMLファイル
    今回はサンプルとして、下記の内容が記述されたXMLファイルを使用します
    <?xml version='1.0' encoding='utf-8'?>
    <root>
        <dir>C:\Bridge Software</dir>
        <class>
            <point>50</point>
            <name>Bridge</name>
        </class>
        <class>
            <point>100</point>
            <name>soft</name>
        </class>
        <class>
            <point>150</point>
            <name>ware</name>
        </class>
        <change>999</change>
    </root>

    pythonスクリプト(読み込み)
    ここでは例として、XMLファイル内から「dir」タグの内容と「name」タグの内容を取得します。
    # -*- coding: UTF-8 -*-
    
    # モジュールのインポート
    import xml.etree.ElementTree as ET
    
    # xmlファイルの読み込み
    tree = ET.parse('test.xml')
    
    # dirタグ
    dir_text = tree.find('dir').text
    print(dir_text)
    
    # nameタグ
    names = tree.findall('class/name')
    for name in names:
        print(name.text)

    実行結果
    ちゃんと読み取れました。


    pythonでフォルダを監視する

    今回はpythonで特定のフォルダを監視し、ファイルの発生や削除などを検知する方法をご紹介します。

    環境
    • macOS Sierra 10.12.5
    • python 3.4
    •  
       
    モジュールのインストール
    今回使用するのは「watchdogモジュール」です。
    Windowsの方はコマンドプロンプト、Macの方はターミナルを起動し、次のコマンドを実行してください。
    >> pip install watchdog

    pipが使用できない場合は以下よりソースファイルを取得し、中のsetup.pyを実行してください。
    https://pypi.python.org/pypi/watchdog

    モジュールの用意が整っている前提で進めます。

    スクリプト
    # -*- coding: utf-8 -*-
    
    from watchdog.events import FileSystemEventHandler
    from watchdog.observers import Observer
    
    import os
    import time
    
    target_dir = "監視したいフォルダのパス"
    
    
    class ChangeHandler(FileSystemEventHandler):
        def on_created(self, event):
            filepath = event.src_path
            filename = os.path.basename(filepath)
            print('%sができました' % filename)
    
        def on_modified(self, event):
            filepath = event.src_path
            filename = os.path.basename(filepath)
            print('%sを変更しました' % filename)
    
        def on_deleted(self, event):
            filepath = event.src_path
            filename = os.path.basename(filepath)
            print('%sを削除しました' % filename)
    
    
    if __name__ in '__main__':
        while 1:
            event_handler = ChangeHandler()
            observer = Observer()
            observer.schedule(event_handler, target_dir, recursive=True)
            observer.start()
            try:
                while True:
                    time.sleep(0.1)
            except KeyboardInterrupt:
                observer.stop()
            observer.join()

    wxPythonでダイアログの多重起動を防止する

    突然ですが、Excelを使ったことはありますか?
    圧倒的大多数の方はYESだと思います。

    Excelの機能の一つに「検索」があります。
    「Ctrl」 + 「F」キーでダイアログが表示されますね。
    あのダイアログ、いくつも同時に表示することはできません。
    でも表示させたままで他の作業をすることはできます。

    よくよく考えたら不思議。
    どうなっているんだろう?

    今回はそんなお話です。

    環境
    • macOS Sierra 10.12.5
    • python 3.4
    • wxPython Phoenix 4.0.0

    悪いスクリプト
    まずは悪い見本のスクリプトを記述します。
    # -*- coding: UTF-8 -*-
    
    import wx
    
    class App(wx.Frame):
        """ GUI """
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(300, 300))
    
            p = wx.Panel(self, wx.ID_ANY)
    
            button = wx.Button(p, wx.ID_ANY, 'click')
            button.Bind(wx.EVT_BUTTON, self.show_dialog)
    
            layout = wx.BoxSizer(wx.VERTICAL)
            layout.Add(button, flag=wx.ALL, border=10)
            p.SetSizer(layout)
    
            self.Show()
    
        def show_dialog(self, event):
            dialog = CustomDialog(self)
            dialog.Show()
    
    
    class CustomDialog(wx.Dialog):
        """ カスタムダイアログ """
    
        def __init__(self, parent):
            wx.Dialog.__init__(self, parent, wx.ID_ANY, 'だいあろぐ', size=(150, 100))
    
            p = wx.Panel(self, wx.ID_ANY)
    
            label = wx.StaticText(p, wx.ID_ANY, 'さんぷる だいあろぐ')
    
            layout = wx.BoxSizer(wx.VERTICAL)
            layout.Add(label, flag=wx.ALL, border=10)
            p.SetSizer(layout)
    
            self.Centre()
    
    
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()

    <実行結果>


    解 説
    悪いスクリプトでは、ボタンのクリックイベント内で別途作成したカスタムダイアログ・クラスを呼び出しています。
    Excelの検索ダイアログのように、ダイアログを表示しながら他の作業ができるようにするにはモードレス表示にする必要がありますので「.ShowModal()」ではなく「.Show()」とする必要があります。

    この場合、多重起動を制御する文を記述していませんので、ボタンをクリックする度にカスタムダイアログが表示されてしまいます。

    良いスクリプト
    # -*- coding: UTF-8 -*-
    
    import wx
    
    class App(wx.Frame):
        """ GUI """
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(300, 300), style=wx.DEFAULT_FRAME_STYLE)
    
            p = wx.Panel(self, wx.ID_ANY)
    
            button = wx.Button(p, wx.ID_ANY, 'click')
            button.Bind(wx.EVT_BUTTON, self.show_dialog)
    
            layout = wx.BoxSizer(wx.VERTICAL)
            layout.Add(button, flag=wx.ALL, border=10)
            p.SetSizer(layout)
    
            self.Show()
    
        def show_dialog(self, event):
    
            if self.FindWindowByName('だいあろぐ') is None:
                dialog = CustomDialog(self)
                dialog.Show()
            else:
                dialog = wx.MessageDialog(self, 'すでに表示されています', 'エラー', wx.ICON_ERROR) 
                dialog.ShowModal() 
                dialog.Destroy()
    
    
    class CustomDialog(wx.Dialog):
        """ カスタムダイアログ """
    
        def __init__(self, parent):
            wx.Dialog.__init__(self, parent, wx.ID_ANY, 'だいあろぐ', size=(150, 100))
    
            p = wx.Panel(self, wx.ID_ANY)
    
            label = wx.StaticText(p, wx.ID_ANY, 'さんぷる だいあろぐ')
    
            layout = wx.BoxSizer(wx.VERTICAL)
            layout.Add(label, flag=wx.ALL, border=10)
            p.SetSizer(layout)
    
            self.Centre()
    
    
    app = wx.App()
    App(None, wx.ID_ANY, 'タイトル')
    app.MainLoop()

    <実行結果> ↓ ↓ ↓

    wxPythonでアプリの多重起動を防止する

    様々なアプリケーションを作成していく中で、「同じアプリケーションが同時に実行されては困る」場合があります。

    今回はwxPythonで複数起動しないように制御する方法をご紹介します。

    環境
    • macOS Sierra 10.12.5
    • python 3.4
    • wxPython Phoenix 4.0.0


    それでは早速スクリプトです。
    # -*- coding: UTF-8 -*-
    
    import wx
    
    class App(wx.Frame):
        """ GUI """
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(300, 300), style=wx.DEFAULT_FRAME_STYLE)
    
            # 二重起動の防止
            self.instance = wx.SingleInstanceChecker(self.GetTitle())
    
            if self.instance.IsAnotherRunning():
                dialog = wx.MessageDialog(None, '%sはすでに起動中です。' % self.GetTitle(), 'エラー', wx.ICON_ERROR)
                dialog.ShowModal()
                dialog.Destroy()
                wx.Exit()
    
            self.Show()
    
    
    app = wx.App()
    App(None, wx.ID_ANY, 'sample')
    app.MainLoop()

    <結果> ↓ ↓ ↓

    pythonでGUIツールを作る ~ ListCtrl (レポートビュー)~

    今回は数あるウィジットの中でもよく使用されるListCtrlについて書いていきます。

    環境
    • macOS Sierra 10.12.5
    • python 3.4
    • wxPython Phoenix 4.0.0

    wxPythonのListCtrlには以下の4つのスタイルがあります。
    1. wx.LC_ICON
    2. wx.LC_SMALL_ICON
    3. wx.LC_LIST
    4. wx.LC_REPORT
    今回はその中のwx.LC_REPORTをご紹介します。
    wx.LC_ICON、wx.LC_SMALL_ICON、wx.LC_LISTの3つについてはこちらをご覧ください。

     wx.LC_REPORTスタイルは「レポートビュー」と呼ばれ、いわゆる「詳細表示」を行うスタイルです。
    フォルダを詳細表示にした時の見た目と通じるものがありますね。


    それではスクリプトを記述します。
    # -*- coding: UTF-8 -*-
    
    import wx
    
    class App(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(400, 300), style=wx.DEFAULT_FRAME_STYLE)
    
            # ステータスバー
            self.CreateStatusBar()
    
            # パネル
            p = wx.Panel(self, wx.ID_ANY)
    
            # インスタンス化
            self.listctrl = wx.ListCtrl(p, wx.ID_ANY, style=wx.LC_REPORT)
            self.listctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.item_select)
    
            # カラム
            self.listctrl.InsertColumn(0, "氏名", wx.LIST_FORMAT_LEFT, 150)
            self.listctrl.InsertColumn(1, "性別", wx.LIST_FORMAT_LEFT, 100)
            self.listctrl.InsertColumn(2, "年齢", wx.LIST_FORMAT_LEFT, 100)
    
            # ListCtrlにアイテムを追加
            for x in range(4):
                self.listctrl.InsertItem(x, '山田 %s郎' % x)
                self.listctrl.SetItem(x, 1, "男")
                self.listctrl.SetItem(x, 2, str((x + 1) * 5))
    
            layout = wx.BoxSizer(wx.VERTICAL)
            layout.Add(self.listctrl, flag=wx.EXPAND | wx.ALL, border=10, proportion=1)
            p.SetSizer(layout)
    
            self.Show()
    
        def item_select(self, event):
            """ アイテム選択時のイベントハンドラー """
            # 選択したアイテムのインデックスを取得する
            select_index = self.listctrl.GetFirstSelected()
    
            # インデックスのアイテムからテキストを取得する
            text0 = self.listctrl.GetItemText(select_index, 0)  # 氏名
            text1 = self.listctrl.GetItemText(select_index, 1)  # 性別
            text2 = self.listctrl.GetItemText(select_index, 2)  # 年齢
    
            item_label = text0 + "は" + text1 + "で" + text2 + "歳です"
    
            # ステータスバーの文字列を変更
            self.SetStatusText(item_label)
    
    app = wx.App()
    App(None, wx.ID_ANY, 'ListCtrl REPORT')
    app.MainLoop()
    

    <結果> ↓ ↓ ↓