2014年3月31日月曜日

文章の修正過程


修正過程の段階


三つの過程からなる。

  1. プリントアウト
  2. プリントへの書き込み
  3. 元データへの反映

プリントアウト


前回のファイルを開き、プリントアウトする。

  • 読みやすさ
  • ある程度文章が詰まっているほうが紙の無駄にならなくていい

というののバランスを考えて、以下の様な形式にしている。二段組。あとファイル名とか日付とかも入るように。




プリントへの書き込み


これを持ち歩き、喫茶店とか集中できるところに行って修正をする。
文章を読み、何か気になることとか不十分だなと感じる箇所があれば、その点について書き込みをする。

  • 入れ替え
  • 文章の付け加え
  • 文章の削除
  • 読みにくい文章を直す
  • 不要な箇所の削除
  • 必要な箇所の追加
  • 誤字の修正

などなど。
基本的に突き詰めて考えなくても、適当にやればいいのだが、個々の作業過程を意識的に分離すると捗ることもある。「今回はどこを削れるか中心に読んでみよう」みたいに。文章を削る作業と、わかりやすくするために追加する作業とは別なのかな、という印象はある。

基本的には余白に書き込むのだが、長くなりそうで書ききれないという場合は、野帳だとからくがき帳だとかに後でわかるように書き込む。

元データへの反映


次は、この書き込みを元のデータに反映する。
もしも、元のデータも残しておきたいという場合であれば、そのコピーをhowm形式で作る。末尾に連番を降るといいかもしれない。あと、修正箇所が多すぎる場合には、元データの修正ではなく、一から書き直す場合もある。

この過程で、元の文章から削ぎ落とす節があるけれども、またもしかしたらつかうかもしれないという場合は、同じフォルダに新しくそのファイルを作り、そこにコピペして保存する。
このようにして修正を終えたら、またそれをプリントアウト。修正して反映して…というのを繰り返す。

だから、フォルダ内には、連番が振られた各バージョンと、反映されずに残っている個々の箇所のファイルとが存在することになる。




その他


DocとかTeXとか


ある程度の分量になり、見出しに階層構造をつけたくなったり引用をつけたくなったりした場合には、Word形式とかTeX形式に移行する。
先の過程で修正をしたhowmファイルをコピペ。見出しとかについて整える。そうして、次からは、これに対して先にしていた修正を行っていく。やることは同じで、

  1. プリントアウト
  2. 書込み
  3. 元のデータに反映

全体と個別


ある程度まで文章が大きくなると、それを全て読んでから修正、という過程が面倒になる。そのようなときは、作業を分割するのがいい。

まずは、文章全体をプリントアウト。これについては、可読性の確保のため、基本あまり書き込みをしないようにする。これを読み、修正が必要だと思われる箇所をチェック。ページ数だとかをどっかにメモっておく。どこどこは修正が必要だというように。
そして、その修正が必要だと判断したページだけをプリント。次からは、その箇所だけを読んで修正作業をする。書き込みもこれに。全体的な文書は、たまに必要なときに参照する、というように。そうして、その書き込みを元データに反映。これを、最初に気になった箇所を全てに対して行う。
それが終われば、全体的な文章をまたプリントアウト、また同じ過程を繰り返す。

CatMemoNoteの利用


ある程度文章が煮詰まってくると、PCのデータ上だけでも修正できるようになる。
その時にはCatMemoNoteを併用する。

データを修正しながら、思いついたことはここにメモ。全体的な構成に関する思いつきは、とりあえずここに書き込む。このような思いつきは賞味期限が短く、howm形式で保存しても後々ノイズになるからだ。
それ以外の思いつきについても、とりあえずここに書き込んでもいい。その場合は、ある程度時間がたてばそれをhowm形式で個別に保存する。

その他、プリントに書き込まれたものを反映させる過程で使う場合がある。その書き込みを元に一旦ここで文章化。CatMemoNote上で編集をし直し、体裁を整えてから元のデータにコピペで反映、ということをする。

2014年3月29日土曜日

CatMemoNoteを使って文章のたたき台を作る

最初


まずは叩き台を作るための、関係するアイデアが書かれているhowmファイルの準備。
howm2のカテゴリーフォルダに関係するメモがあるはずなので、ふつうはそれを使う。

まとめる


CatMemoNoteを起動。PPvでhowmファイルを閲覧しながら、気になったことをメモをしていく。





すべてのファイルを閲覧し終わったら、このメモを構成しなおす。単純に入れ替えればそれで済むのであればCatMemoNote上で。もう少しややこしそうならば、新たにエディタを開き、CatMemoNoteに書かれたメモを参考にしながら文章を作る。

もちろんhowmファイルを作成してそこに書くのでもいいし、あーでもこれ文章なるのかなーとか不安なのであれば、xyzzyのスクラッチを開いてそこに書き、それで都合が悪くなれば全消しして、というのでもいい。

フォルダ移動


このようにしてできた叩き台の文章を、howm形式で保存する。

そのときには、これまでのアイデアメモがあったのとは別のカテゴリーフォルダをhowm2に新たに作成して、そこに入れる。だから、この時点では、そのフォルダには一つしかファイルが入っていない状態になる。


 とりあえずここまでがひとつの過程。次からは、これを修正する過程に移る。

2014年3月25日火曜日

文章のたたき台を作る過程の変遷


あいさつ


つかさです。
今回は、たまったテキストファイルのメモを元にして、まとまった文章を作る方法論です。具体的にはA4で5枚分以上くらいの分量を想定してます。

二つの段階


その過程だが、二つに分けることが出来ると思う。

  • たたき台を作る
  • それを修正していく

修正段階


後者については今までで方法論はほぼ確立している。基本的には、

  1. 草稿をプリントアウト
  2. そのプリントに書き込みを加えて
  3. 修正元のデータに反映させる

を繰り返すことで行う。


その1 書いた文書をプリントアウトする


モノクロレーザープリンタがあれば便利。無ければコンビニでPDFプリントとかになる。

その2 プリントに書き込みを加えて修正


プリントしたものを読み、修正していく。書き加えとか入れ替えなどなど。
基本的にはプリントにボールペンで修正を書き込んでいく。もし大きく変えたい部分や、新しく思いついたことなどがあれば、どの箇所の修正なのかわかるようにして野帳や計算用紙に書くのでもいい。
この過程は適当にやればいいのだが、個々の過程を意識的に分離して行うと捗る気がする。

その3 元のデータに反映


そうして訂正したプリントを元にして、元のデータを修正する。この時は、元のファイルを直接編集するのでもいいし、元データは残し、そのデータをコピーしたhowmファイルを新しく作ってそれを編集するのでもいい。
また、構成上元のデータから削除したい箇所があるが、あとで使うかもしれないと思うものは、新しくhowmファイルを作ってそこにコピーし、保存する。

まとめ


これを繰り返すことで、徐々に文章を完成に近づけていく。最初のたたき台は適当なものでいい。この過程で、必要だけど考察が済んでいないところだとかが明らかになるはずだから、それについて個別にリストアップし、埋めていく。

ある程度文章が大きくなって、見出しなどでも階層構造を付けたくなったときには、TeXなりWordファイルなりの形式にして同じ過程を繰り返す。

たたき台を作る段階


だが、前者についてはこれまでまとまったものがなかった。一応色々模索はしてたが、あまりこれというものがなかった。

前提


howmフォルダに、いくつかアイデアメモがたまっているというのが前提。そのメモをPC上でまとめる方法を模索する。
PCを使わない方法としては、例えばたまったメモをClipMarkFile.jsでクリップボードにコピー、それを印刷してそれを元にして考察するという方法があり得る。だが、何度かやったけれどもあまりうまくいかなかった。あと、適当にコピペして一つの文章に無理矢理したりもしてたが、原始的すぎてこれもどうかなというのがあった

メモのメモ


これは、メモからメモを作る環境をどうやって整えるかという問題になる。たまったメモを見ながら、思いついたこととか使えそうな部分をメモにとって、それを元にして文章を作るのだ。

メモを閲覧した直後に、そこで頭に残ったことを元にしてまとまった文章を書けるというのであれば一番早いのだが、そもそもメモが構成だったものではない以上無理そうだ。どこかにメモを書出し、それを構成し直すという過程が必要になる。

アナログだったら、何か図を書くとかそれぞれのメモの連関図を作るとか何かいろいろあり得るのかもしれないが、基本的には文字だけで十分じゃないかと僕は思っている。

たたき台を作る過程の変遷


このメモをどうやってとるかだが、

  1. howmファイルにメモ
  2. ChangeLogにメモ
  3. CatMemoNoteにメモ

という変遷をたどった。

その1 howmファイルにメモ


メモを閲覧するフォルダのなかに、メモ用のhowmファイルを作成して、そこにメモをしていく。
他のメモとごっちゃになり、後で続きをやるときに取り出しにくいというデメリットや、途中でメモをまとめる作業を中断してしまった場合、このファイルがノイズになってしまうというデメリットがあった。

その2 ChangeLogにメモ


別に今までと同じようにhowmファイルの形式にする必然性無いよなと気づいて、次に試したのがChangeLog。本来はプログラムの変更履歴を書き留めるテキスト形式だが、メモにも使える。
特定のファイルを開いている時にこれを呼び出すと、呼び出し元のファイル名とか日付とか入力された状態でこのメモが開くという仕組み。これだと他のメモに埋もれる心配も無い。ただ、ひとつのフォルダに一つのメモしか作成できないということと、メモは基本PPvで閲覧するからChangeLogを呼び出すのがやりにくいという理由からやめる。

その3 CatMemoNoteにメモ


考えれば、ここで作るメモはずっと残っている必要もないし、ファイルとしてきちんと残すとか考える必要特に無いよなと気づいて、試したのがCatMemoNote。
これは一時的なメモに特化したソフト。メモの作成も削除も容易だし、ウィンドウの表示非表示もホットキーでできる。というわけで今はこれに落ち着いています。

具体的な使い方


howm2のカテゴリーフォルダをPPvで閲覧する。CatMemoNoteをひらき、気になったことをコピペしたり、思いついたことを書き込んだりする。
メモを閲覧し終えたら、CatMemoNoteに書き込まれたメモを元にして再構成する。順番入れ替えたり文章を付け加えたりなど。あるいは、ここに書き込まれたのを参考にしながら、エディタを開き文章を作ってもいい。

備考


  • 見出しをつけるのは面倒なので、日付の定型文を区切りに入れる
  • 時間が経過した書き込みはhowm形式にして保存、書き込みを消す
  • このメモを元にしてさらにメモを書きたい場合はxyzzyのスクラッチを利用する
  • 途中で思いついたことは、CatMemoNoteの別ウィンドウに書き込んでもいい
  • 何か適当なことを書きたい場合は、まずCatMemoNoteに書いてからhowmにするのでもいい

2014年2月18日火曜日

ほむランチャ ver0.01 公開

あいさつ


以前作ったほむランチャを、py2exeでexe化してHPに公開した(ほむランチャ - hoehoeSoft)。


ほむランチャは、PPxでステップイン・ステップアウトする方法ないかなと考えて試作したもの。基本的にはファイラの補助としての使用を想定している。
というわけで使い方の紹介。

準備


まずはhomu.iniを編集して、open_folder_cmdを

open_folder_command = D:\bin\ppw\PPCW.EXE  -r {folder}

とする。

次に、PPxの適当なキーにほむランチャを登録する。以下を編集して取込。

KC_main = { ; PPcメイン窓
G ,%Obi D:\bin\hlnch\hlnch.exe %1
}

もしもPPcウィンドウの真ん中に表示させたいなら、PPXMES.DLLとPPXWIN.DLLをPPxフォルダにおいて以下を編集して取込。

KC_main = { ; PPcメイン窓
G ,%Obi D:\bin\hlnch\hlnch.exe %1 %: *fitwindow %NC,%*findwindowtitle("HomuLauncher"),20
}

これで準備はおk。

使い方



  1. ほむランチャを起動
  2. 移動したいフォルダにカーソル移動
  3. Enter


これでフォルダジャンプができる。

他のキーの登録


homu.iniの[KEY]セクションを編集することで、他のコマンドを任意のキーに登録することができる。たとえば

c-o = D:\bin\ppw\PPCW.EXE -r -noactive -bootid:~ {folder}
c-enter = D:\bin\ppw\PPCW.EXE -r -noactive -bootid:~ {folder}
c-a = D:\bin\afxw\AFXW.EXE -s -p{folder}
c-c = D:\bin\ppw\PPCW.EXE -r -k *ppcfile copy,{folder}
c-m = D:\bin\ppw\PPCW.EXE -r -k *ppcfile move,{folder}

とすれば、

  • Ctrl+Enter→PPxの反対窓で開く
  • Ctrl+O→PPxの反対窓で開く
  • Ctrl+A→あふで開く
  • Ctrl+C→PPxのカーソルファイルをほむランチャで表示しているフォルダにコピー
  • Ctrl+M→PPxのカーソルファイルをほむランチャで表示しているフォルダに移動

ができる。

置換マクロには
  •  {path}  .....  パス名
  •  {folder}  .....  フォルダ名
が使用可能。

その他


あふとか他のファイラでも使えるが、ほむランチャ自体には表示位置を調整する機能が無いので微妙かもしれない。可能ならコマンドラインオプションで前のウィンドウの真ん中に移動とかできるようにしたいがとりあえず今のところやり方を知らない
あと、dataフォルダのsort.txtを編集することでフォルダごとにソート状態を変更できたり、homu.iniをいじってファイルを表示したりもできる。

ちなみに僕のhomu.iniは以下

[MAIN]
historymode = 1
x = 300
y = 300
showfile = 1
mainwindowwidthadd = 22
open_folder_command = D:\bin\ppw\PPCW.EXE  -r {folder}
open_file_command = D:\bin\ppw\PPCW.EXE  -r {folder}
start_folder = 
selecttype = 0

[KEY]
c-a = D:\bin\afxw\AFXW.EXE -s -p{folder}
c-enter = D:\bin\ppw\PPCW.EXE -r -noactive -bootid:~ {folder}
c-c = D:\bin\ppw\PPCW.EXE -r -k *ppcfile copy,{folder}
c-m = D:\bin\ppw\PPCW.EXE -r -k *ppcfile move,{folder}


[HISTORY]
x = 300
y = 300

2014年2月9日日曜日

wxPythonで常駐ランチャをつくろう!第三回 タスクトレイアイコンの表示

あいさつ


つかさです。今回はタスクトレイアイコンの表示。


タスクトレイアイコンを

  • 右クリックでメニューを表示
  • 左ダブルクリックで表示、非表示のトグル

できるようにします。

以下のコードを保存。同じフォルダにhomu.icoという名前の適当なアイコンをおいてから、実行してください。


hlnch03.py

# -*- encoding: utf-8 -*-

import wx,subprocess,os,sys,SocketServer,socket,threading

class MyTxtCtr(wx.PySimpleApp):
    
    def OnInit(self):
        HOST, PORT = socket.gethostname(), 61955
        argvs = sys.argv

        instance_name = u"%s-%s" % (self.GetAppName(), wx.GetUserId())
        self.instance = wx.SingleInstanceChecker(instance_name)
        if self.instance.IsAnotherRunning():
            if len(argvs) >= 2:
                self.client(HOST, PORT, argvs)
            wx.Exit()
        else:
            server = self.start_server(HOST, PORT)

        # タスクトレイ
        self.tb_ico=wx.TaskBarIcon()
        self.tb_ico.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTbiLeftDClick)
        self.tb_ico.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.OnTbiRightUp)
        self.ico = wx.Icon("homu.ico", wx.BITMAP_TYPE_ICO)
        self.tb_ico.SetIcon(self.ico, u"homuhomu")

        # タスクトレイ用メニューの作成
        self.menu = wx.Menu()
        self.menu.Append(1,   u"Exit(&X)")
        wx.EVT_MENU(self.menu, 1, self.OnClose)

        self.Frm = wx.Frame(None, -1, "homuLauncher", size=(400,60),pos=(400,400))
        self.TxtCtr = wx.TextCtrl(self.Frm, -1)
        self.Frm.Show()
        return 1

    def start_server(self,host, port):

        server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler)
        ip, port = server.server_address
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.setDaemon(True)
        server_thread.start()

    def client(self,ip, port, argvs):
        message = os.path.abspath(' '.join(argvs[1:]))
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((ip, port))
        sock.send(message)
        response = sock.recv(1024)
#        print "Received: %s" % response
        sock.close()

    # タスクトレイ左ダブルクリック
    def OnTbiLeftDClick(self, evt):
        if self.Frm.IsShown():
            self.Frm.Show(False)
        else:
            self.Frm.Show()
            self.Frm.Raise()
            
    # タスクトレイ右クリック
    def OnTbiRightUp(self, evt):
        self.tb_ico.PopupMenu(self.menu)

    def OnClose(self, evt):
        self.tb_ico.RemoveIcon()
        wx.Exit()

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        wx.GetApp().TxtCtr.SetValue(data)
        response = 'string length: %d' % len(data)
#        print 'responding to',data,'with',response
        self.request.send(response)
        
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

app = MyTxtCtr()
app.MainLoop()

解説


        self.tb_ico=wx.TaskBarIcon()
        self.tb_ico.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTbiLeftDClick)
        self.tb_ico.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.OnTbiRightUp)
        self.ico = wx.Icon("homu.ico", wx.BITMAP_TYPE_ICO)
        self.tb_ico.SetIcon(self.ico, u"homuhomu")

  1. タスクトレイアイコンのインスタンスを作成
  2. タスクトレイアイコンをクリックした時のイベントをセット
  3. アイコン画像をセット

というようにしてます。

左ダブルクリック


    # タスクトレイ左ダブルクリック
    def OnTbiLeftDClick(self, evt):
        if self.Frm.IsShown():
            self.Frm.Show(False)
        else:
            self.Frm.Show()
            self.Frm.Raise()

メインウィンドウが表示されてるかどうかを取得し、表示されていれば非表示に。非表示ならば表示にしてます。

右クリック


        # タスクトレイ用メニューの作成
        self.menu = wx.Menu()
        self.menu.Append(1,   u"Exit(&X)")
        wx.EVT_MENU(self.menu, 1, self.OnClose)

クリックした時のメニューは

  1. メニューインスタンスを作成
  2. そこに表示項目を追加し
  3. それに対応するイベントをセット

のように作成。このようにして作ったメニューを

    # タスクトレイ右クリック
    def OnTbiRightUp(self, evt):
        self.tb_ico.PopupMenu(self.menu)

で登録してます。

wxPythonで常駐ランチャをつくろう!第二回 実行中のファイルに引数を渡す

あいさつ


つかさです。今回は、実行中のプログラムへの引数の送り方です。
メインウィンドウの文字列を与えられた引数に置き換えます。

例えば、既にランチャが起動しているときに

D:\bin\homuLauncher\htest2.py H:\howm2\Python

とすれば実行中のウィンドウがこんな感じになるようにします。



hlnch02.py

# -*- encoding: utf-8 -*-

import wx,subprocess,os,sys,SocketServer,socket,threading

class MyTxtCtr(wx.PySimpleApp):
    
    def OnInit(self):
        HOST, PORT = socket.gethostname(), 61955
        argvs = sys.argv
        instance_name = u"%s-%s" % (self.GetAppName(), wx.GetUserId())
        self.instance = wx.SingleInstanceChecker(instance_name)
        if self.instance.IsAnotherRunning():
            if len(argvs) >= 2:
                self.client(HOST, PORT, argvs)
            wx.Exit()
        else:
            server = self.start_server(HOST, PORT)
        self.Frm = wx.Frame(None, -1, "homuLauncher", size=(400,60),pos=(400,400))
        self.TxtCtr = wx.TextCtrl(self.Frm, -1)
        self.Frm.Show()
        return 1

    def start_server(self,host, port):
        server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler)
        ip, port = server.server_address
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.setDaemon(True)
        server_thread.start()

    def client(self,ip, port, arg):
        message = os.path.abspath(' '.join(arg[1:]))
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((ip, port))
        sock.send(message)
        response = sock.recv(1024)
#        print "Received: %s" % response
        sock.close()

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        wx.GetApp().TxtCtr.SetValue(data)
        response = 'string length: %d' % len(data)
#        print 'responding to',data,'with',response
        self.request.send(response)
        
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

app = MyTxtCtr()
app.MainLoop()

説明


  1. 初回起動時に、本体と共にバックグラウンドでサーバーを起動する。そのサーバーが何かメッセージを受け取れば、それに応じて本体に反映させるようにしておく
  2. 二度目の起動時には、そのサーバーに接続するクライアントを作成。引数を渡し、自身は終了する

という構造です。
ポート番号を予め指定し、サーバーとクライアントを作ることで、初回起動時のプログラムと二度目以降のとをつなげるという仕組みらしい。もっと簡単にできると思ってたけどわりと大掛かりなんですね。それとも他の方法があるのかしらん。

解説


二重起動のチェック


        if self.instance.IsAnotherRunning():
            if len(argvs) >= 2:
                self.client(HOST, PORT, argvs)
            wx.Exit()
        else:
            server = self.start_server(HOST, PORT)


wx.SingleInstanceCheckerで、既に起動中のプログラムがあるかどうかで分岐。

  • 初回起動なら サーバーをバックグラウンドで起動する
  • 既に起動しているなら クライアントを作成して、既に起動中のプログラムのサーバーに接続する

という具合です。それぞれstart_serverとclientで行ってます。

サーバー側


    def start_server(self,host, port):

        server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler)
        ip, port = server.server_address
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.setDaemon(True)
        server_thread.start()


ここでサーバーを動かしてるわけですが、二つのクラスを利用してます。

1 ThreadedTCPRequestHandlerクラス

クライアントからメッセージを受け取った時の処理をThreadedTCPRequestHandlerクラスで定めます。

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        wx.GetApp().TxtCtr.SetValue(data)
        #Note to the self.server.app
        response = 'string length: %d' % len(data)
#        print 'responding to',data,'with',response
        self.request.send(response)


受け取ったデータを、SetValueでテキストボックスに貼り付けてますね。

2 ThreadedTCPServerクラス

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass


非同期的な動作をサポートするのにこれが必要らしい。参考にしたのがこうしてたのでとりあえずこうしてます。


クライアント側


    def client(self,ip, port, arg):
        message = os.path.abspath(' '.join(arg[1:]))
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((ip, port))
        sock.send(message)
        response = sock.recv(1024)
#        print "Received: %s" % response
        sock.close()


  1. ソケットを作成
  2. サーバーに接続
  3. コマンドライン引数をサーバーに送る
  4. レスポンスを受け取り
  5. 終了

という順序ですね。

2014年2月7日金曜日

wxPythonで常駐ランチャをつくろう!第一回 多重起動の防止

あいさつ


つかさです。常駐ランチャを作ってみます。

1 多重起動の防止
2 実行中のファイルに引数を投げる
3 アイコン表示

の三回の予定です。今回は多重起動の防止。



説明の簡略化のため、テキストコントロールだけを表示します。
ランチャっぽいものをどう作るか自体は、Pythonでコマンドラインランチャを作ろう!シリーズの記事を参考にしてください。そのあたりの記事と組み合わせたら常駐ランチャにおそらくなります。 

hlnch01.py
# -*- encoding: utf-8 -*-

import wx

class MyTxtCtr(wx.PySimpleApp):
    
    def OnInit(self):
        instance_name = u"%s-%s" % (self.GetAppName(), wx.GetUserId())
        self.instance = wx.SingleInstanceChecker(instance_name)
        if self.instance.IsAnotherRunning():
            wx.MessageBox("Another instance is running", "ERROR")
            return False
        self.Frm = wx.Frame(None, -1, "homuLauncher", size=(400,60),pos=(400,400))
        self.TxtCtr = wx.TextCtrl(self.Frm, -1)
        self.Frm.Show()
        return 1

app = MyTxtCtr()
app.MainLoop()

説明


要は

wx.SingleInstanceChecker

を使えばいい、ということですね。

instance_name = u"%s-%s" % (self.GetAppName(), wx.GetUserId())

でファイル名とユーザーIDからなる文字列を取得。これと同じものが起動中かどうかをIsAnotherRunning()で判別し、既に起動していればエラーメッセージを出して終了するようにしてます。

参考


OneInstanceRunning - wxPyWiki