リンク

2017年6月27日火曜日

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()

<結果> ↓ ↓ ↓

2017年5月3日水曜日

pythonでGUIツールを作る ~ ListCtrl (大アイコン、小アイコン、リスト)~

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

wxPythonのListCtrlには以下の4つのスタイルがあります。

  • wx.LC_ICON
  • wx.LC_SMALL_ICON
  • wx.LC_LIST
  • wx.LC_REPORT

今回はその中のwx.LC_ICON、wx.LC_SMALL_ICON、wx.LC_LISTの3つを一気にご紹介します。

それではいきなりスクリプトです。
# -*- coding: UTF-8 -*-

import wx

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

        # ステータスバー
        self.CreateStatusBar()

        # パネル
        p = wx.Panel(self, wx.ID_ANY)

        # ListCtrl0 大アイコン - - - - - - - - - - - - - - - - - - - - - - - - - - -
        self.listctrl = wx.ListCtrl(p, wx.ID_ANY, style=wx.LC_ICON)
        self.listctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.item_select)

        # イメージリスト
        imagelist = wx.ImageList(32, 32)
        imagelist.Add(wx.Icon("a.png", wx.BITMAP_TYPE_PNG))
        imagelist.Add(wx.Icon("b.png", wx.BITMAP_TYPE_PNG))
        imagelist.Add(wx.Icon("c.png", wx.BITMAP_TYPE_PNG))
        imagelist.Add(wx.Icon("d.png", wx.BITMAP_TYPE_PNG))

        # ListCtrlにイメージリストを割り当て
        self.listctrl.AssignImageList(imagelist, wx.IMAGE_LIST_NORMAL)

        # ListCtrlにアイテムを追加
        for x in range(4):
            self.listctrl.InsertItem(x, 'item_%s' % x, x)

        # ListCtrl1  小アイコン - - - - - - - - - - - - - - - - - - - - - - - - - - -
        self.listctrl1 = wx.ListCtrl(p, wx.ID_ANY, style=wx.LC_SMALL_ICON)

        # イメージリスト
        imagelist1 = wx.ImageList(16, 16)
        imagelist1.Add(wx.Icon("a.png", wx.BITMAP_TYPE_PNG))
        imagelist1.Add(wx.Icon("b.png", wx.BITMAP_TYPE_PNG))
        imagelist1.Add(wx.Icon("c.png", wx.BITMAP_TYPE_PNG))
        imagelist1.Add(wx.Icon("d.png", wx.BITMAP_TYPE_PNG))

        # ListCtrlにイメージリストを割り当て
        self.listctrl1.AssignImageList(imagelist1, wx.IMAGE_LIST_SMALL)

        # ListCtrlにアイテムを追加
        for y in range(4):
            self.listctrl1.InsertItem(y, 'item_%s' % y, y)

        # ListCtrl1  リスト - - - - - - - - - - - - - - - - - - - - - - - - - - -
        self.listctrl2 = wx.ListCtrl(p, wx.ID_ANY, style=wx.LC_LIST)

        # イメージリスト
        imagelist2 = wx.ImageList(16, 16)
        imagelist2.Add(wx.Icon("a.png", wx.BITMAP_TYPE_PNG))
        imagelist2.Add(wx.Icon("b.png", wx.BITMAP_TYPE_PNG))
        imagelist2.Add(wx.Icon("c.png", wx.BITMAP_TYPE_PNG))
        imagelist2.Add(wx.Icon("d.png", wx.BITMAP_TYPE_PNG))

        # ListCtrlにイメージリストを割り当て
        self.listctrl2.AssignImageList(imagelist2, wx.IMAGE_LIST_SMALL)

        # ListCtrlにアイテムを追加
        for z in range(4):
            self.listctrl2.InsertItem(z, 'item_%s' % z, z)

        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(self.listctrl, flag=wx.EXPAND | wx.ALL, border=10, proportion=1)
        layout.Add(self.listctrl1, flag=wx.EXPAND | wx.ALL, border=10, proportion=1)
        layout.Add(self.listctrl2, flag=wx.EXPAND | wx.ALL, border=10, proportion=1)
        p.SetSizer(layout)

        self.Show()

    def item_select(self, event):
        """ アイテム選択時のイベントハンドラー """
        # 選択したアイテムのインデックスを取得する
        select_index = self.listctrl.GetFirstSelected()

        # インデックスのアイテムからテキストを取得する
        item_label = self.listctrl.GetItemText(select_index)

        # ステータスバーの文字列を変更
        self.SetStatusText(item_label + "を選択しました")


app = wx.App()
App(None, wx.ID_ANY, 'ListCtrl')
app.MainLoop()

<結果> ↓ ↓ ↓

wxPythonのイメージリスト

今回はwxPythonの様々なウィジットで使用すImageList(イメージリスト)について書いていきます。

ImageListはその名の通り、”イメージの集まり”です。
ListCtrlやTreeCtrl、Menuなどで主に使用します。

例えば、ListCtrlにアイテムを追加する際、偶数の項目にはA.pngを、奇数の項目にはB.pngを当てはめる、といった具合です。

ImageListを使用する利点は「インデックスだけで画像を指定できる」という点です。
上記程度の内容であれば、直接イメージファイルを指定してもいいのですが、例えば「拡張子に対応したイメージを割り当てる」といった場合は結構面倒です。

そこでImageListが活躍します。

下記のスクリプトはListCtrlにImageListを適用するサンプルです。
# -*- coding: UTF-8 -*-

import wx

imagelist = wx.ImageList(32, 32)
imagelist.Add(wx.Icon("a.png", wx.BITMAP_TYPE_PNG))
imagelist.Add(wx.Icon("b.png", wx.BITMAP_TYPE_PNG))
imagelist.Add(wx.Icon("c.png", wx.BITMAP_TYPE_PNG))
imagelist.Add(wx.Icon("d.png", wx.BITMAP_TYPE_PNG))

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)

        self.listctrl = wx.ListCtrl(p, wx.ID_ANY, style=wx.LC_ICON)
        
        # ListCtrlにイメージリストを割り当て
        self.listctrl.AssignImageList(imagelist, wx.IMAGE_LIST_NORMAL)

        # ListCtrlにアイテムを追加
        for x in range(4):
            self.listctrl.InsertItem(x, 'item_' + str(x), x)

        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(self.listctrl, flag=wx.EXPAND | wx.ALL, border=10, proportion=1)
        p.SetSizer(layout)

        self.Show()

app = wx.App()
App(None, wx.ID_ANY, 'タイトル')
app.MainLoop()

<結果> ↓ ↓ ↓

2017年1月4日水曜日

pythonでGUIツールを作る ~ ドラッグ&ドロップ ~

今回はwxPythonを使用したGUIツールにドラッグ&ドロップ(以下D&D)を実装します。

D&Dを実装するのは意外と簡単で、wx.FileDropTargetクラスを使用します。
早速スクリプトを見ていきます。
# -*- coding: UTF-8 -*-

import wx

class FileDropTarget(wx.FileDropTarget):
    """ Drag & Drop Class """
    def __init__(self, window):
        wx.FileDropTarget.__init__(self)
        self.window = window

    def OnDropFiles(self, x, y, files):
        self.window.text_entry.SetLabel(files[0])

        return 0


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

        # パネル
        p = wx.Panel(self, wx.ID_ANY)

        label = wx.StaticText(p, wx.ID_ANY, 'ここにファイルをドロップしてください', style=wx.SIMPLE_BORDER | wx.TE_CENTER)
        label.SetBackgroundColour("#e0ffff")

        # ドロップ対象の設定
        label.SetDropTarget(FileDropTarget(self))

        # テキスト入力ウィジット
        self.text_entry = wx.TextCtrl(p, wx.ID_ANY)

        # レイアウト
        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add(label, flag=wx.EXPAND | wx.ALL, border=10, proportion=1)
        layout.Add(self.text_entry, flag=wx.EXPAND | wx.ALL, border=10)
        p.SetSizer(layout)

        self.Show()

app = wx.App()
App(None, -1, 'タイトル')
app.MainLoop()

<結果> ↓ ↓ ↓

pythonでGUIツールを作る ~ クローズイベント ~

今回はwxPythonで作成したフレームを閉じる(≒アプリを終了する)際に何らかの処理を行いたい場合の記述方法をご紹介します。
# -*- 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.Bind(wx.EVT_CLOSE, self.frame_close)

        # パネル
        p = wx.Panel(self, wx.ID_ANY)

        self.Show()

    def frame_close(self, event):
        """ 閉じたときに発生するイベント """
        wx.MessageBox('イベント発生!', 'title')

        #event.Skip()
        self.Destroy()

app = wx.App()
App(None, -1, 'タイトル')
app.MainLoop()

<結果> ↓ ↓ ↓

2017年1月3日火曜日

pythonでGUIツールを作る ~ 画像のリサイズ ~

wxPythonでGUIツールを作る際、wx.BitmapButtonなどを使用するとき画像サイズとボタンサイズが合わず、小さいorはみ出してしまうといった場合があります。

今回は画像サイズをウィジットに合わせるようリサイズする方法をご紹介します。

今回はこの画像を使用します。

2017年1月2日月曜日

pythonでGUIツールを作る ~ ポップアップメニュー ~

wxPythonのwx.Menuを使って、右クリックで表示されるポップアップメニューを作成します。

wx.Menuについては別の記事で紹介しておりますのでそちらをご覧ください。
pythonでGUIツールを作る ~ Menubar&Menu メニューバー&メニュー ~
# -*- coding: utf-8 -*-

import wx


def rclick(event):
    """ 右クリックイベント """
    frame.PopupMenu(menu_file)


def menu_select(event):
    """ メニュー選択イベント """
    id = event.GetId()

    if id == 1:
        print('開く')
    elif id == 2:
        print('保存')
    elif id == 3:
        print('削除')
    else:
        print('終了')


application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, "テストフレーム", size=(300,200))

panel = wx.Panel(frame, wx.ID_ANY)

label = wx.StaticText(panel, wx.ID_ANY, '右クリックでメニューを表示します', pos=(20, 30))

# メニュー
menu_file = wx.Menu()

item_1 = wx.MenuItem(menu_file, 1, '開く')
item_2 = wx.MenuItem(menu_file, 2, '保存')
item_3 = wx.MenuItem(menu_file, 3, '削除')
item_4 = wx.MenuItem(menu_file, 4, '終了')

menu_file.Append(item_1)
menu_file.Append(item_2)
menu_file.Append(item_3)
menu_file.Append(item_4)

# メニューアイテム選択イベント
menu_file.Bind(wx.EVT_MENU, menu_select)

# パネル上で右クリックしたときのイベント
panel.Bind(wx.EVT_RIGHT_DOWN, rclick)

frame.Show()
application.MainLoop()

<結果>

上記スクリプト内で、過去に解説した内容については省略致します。
ご確認いただきたい場合は、pythonでGUIツールを作る ~基礎編~をご覧ください。

続いて解説を行います。