PyQt4

やばいよPtQt4。PythonとQtがこんなにも相性が良かったとは。

まずQt Designerとの相性が良い。Designerはシグナル/スロットの管理は出来るけど、低レベルイベントのカスタマイズが出来ないんだよね。Qtのイベント処理はウィジェットクラスの継承とprotectedメソッドのオーバーライドによって行なうんだけど、Designerを使うとそれが面倒くさい(これがザウルスのQt開発でDesignerを使ってない理由)。QFrameとかを継承したクラスを作ってDesignerに読み込ませたり(面倒)、eveneFilterを使ったり(面倒)。でもPythonなら動的にクラスをいじれるので、

mainwindow_form, mainwindow_base = uic.loadUiType('mainwindow.ui')

class MainWindow(mainwindow_base, mainwindow_form):
    def __init__(self):
        mainwindow_base.__init__(self)

        ## フォーム構築
        self.setupUi(self)

        ## イベントハンドラのオーバーライド
        self.inputFilesList.__class__.dragEnterEvent = self.dragEnterEvent
        self.inputFilesList.__class__.dragMoveEvent = self.dragEnterEvent
        self.inputFilesList.__class__.dropEvent = self.dropEvent

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()

    def dropEvent(self, event):
        for url in event.mimeData().urls():
            self.addInputFile(url)

こんな感じでDesignerで作成したウィジェットのイベントをオーバーライドできる。素晴しい。ついでにuiファイルをコードに変換しなくても直接読み込める。素晴しい(C++のほうでも出来るらしいけど)。

あとQStringとPythonの文字列、QPair とPythonのタプル、QListとPythonのリストの変換を暗黙的にやってくれたり。こんな複雑な型の引数を持つメソッドも、

>>> ## void QUrl::setQueryItems ( const QList > & query );
>>> url = QUrl()
>>> url.setQueryItems([('action', 'view'), ('page', 'index')])
>>> unicode(url.toString())
?action=view&page=index

って書ける。感動した。このへんはSIPの凄さなのかなぁ。

問題は配布するときのファイルサイズかな。py2exeを使うと、Python処理系+Qt+PyQtで10MBを越えそうな気がする。