Python GUI Spyder と Qt Designer で かんたん GUI 開発

Python と PyQt を使うことで、簡単なGUIユーティリティをつくるのは非常に簡単になった。

のだが、やはりGUIをコードでしこしこかくのは面倒なので、ツールを使いたい。

ということで、PyQt に含まれている、Qt Designer の使い方を覚えようと思う。

ちなみに、配布まで考えると、Portable Python で試した方がよいかと思ったら、今は開発が止まっているようで、WinPython 環境、および 同梱されている、Spyder というIDEを利用してみるが、基本的にはどんな環境でも同じだと思う。

1.Spyder プロジェクトを作成

WinPython をダウンロードインストールすると、ディレクトリに、Spyder.exe があるので、これを起動する。WinPython 自体は、有用なパッケージ(PyQtも含まれている)を含んだ独立したPython環境で、Windows 自体のレジストリなどの環境を基本的には汚染しない。

1.1 Spyderワークスペースの作成

IDE Spyder のプロジェクトを作成する。

メニューから New project。

winpy01

現在のワークペースが構成されていないから、構成するか?と訪ねられるので YES

winpy02

ワークスペースとは何かの説明が表示されるので、以下のように理解してOK

Spder のワークスペースは、複数のSpyderプロジェクトや、.spyderworkspace 設定ファイルを含む、ファイルシステム上のディレクトリ。

Spyder プロジェクトは、ソースコード(および関連ファイル)や設定ファイル(.spyderproject) とともに、設定(PYTHONPATH、リンクされたプロジェクトなど)を含むディレクトリ。

winpy03

指定したディレクトリを、Spyderワークスペースとして構成しますかきかれるので、YES

winpy04

1.2 Spyder プロジェクトの作成

晴れて、プロジェクトが作成出来るようになったので、プロジェクトエクスプローラー(表示されていない場合、メニュー - View ー Panes) のコンテキストメニューから、New project

winpy05

プロジェクト名を、gui_sample とでもして、OK

winpy06

1.3 パッケージの作成

ui ファイル用のパッケージをプロジェクトのコンテキストメニューから、New – Package で作成。ui とでもしておく。ここに、Qt Designer で作成したファイルを置く。

winpy14

2. Qt Designer でGUIの作成

http://web.eng.hawaii.edu/~bsb/me696_f14/assign/gui_qt4_ex.html

同様に、WinPython のインストールディレクトリの、Qt Designer.exe を起動する

2.2 起動時にウィザードが立ち上がるので、Widgetを選択してみる

winpy07

適当にコントロールを配置。

Qt Designer 自体の使い方は、Qt Designer使い方入門 がわかりやすい。

以下のように、フォーム上にテキストボックスと、ボタンを2つ配置する

winpy08

試しに、F4 を押して、シグナル/スロットを編集 モード にし、左下のボタンが押下されたら、テキストを選択状態にするように設定してみる。

winpy09

winpy10

オブジェクトの名前をプロパティペインから、

テキストボックス : txt_message

OK ボタン : btn_ok とでもしておく

winpy12

作成したフォームを保存する。

保存するときに、上記 Spyder で作成した、ui パッケージのディレクトリに保存しておく。

winpy11

3.UI設定ファイルの変換

Qt Designer で作成した、UIは、XMLのファイルとして作成されるため、これを Python のファイルに変換させる。

GUIは、Qt Designer で作成/編集 を行いたいので、基本的にUIのファイルは編集しないですむように開発環境を整えたい。

ということで、UI XML を Python に変換する Pythonスクリプトを、ui パッケージに配置し、

  1. Qt Designer で UIを編集 –> 保存
  2. 変換スクリプト
  3. 処理をコーディング

という流れにしたい。

以下は、最低限の変換コード、タイムスタンプを比較して自動で変換を走らせたりと、高機能出来そうだが、まずは、今回上記で作成した、ui ファイルを変換させる

ui.convert_qt.py

# -*- coding: utf-8 -*-
from PyQt4 import uic

fin = open('first_form.ui', 'r')
fout = open('first_form.py', 'w')
uic.compileUi(fin,fout,execute=False)
fin.close()
fout.close()

以下が、変換されて生成されたファイル。このファイルに修正を加えても失われちゃうよ!との注意書き。

ui.first_form.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'first_form.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(368, 140)
        self.btn_ok = QtGui.QPushButton(Form)
        self.btn_ok.setGeometry(QtCore.QRect(270, 100, 75, 23))
        self.btn_ok.setObjectName(_fromUtf8("btn_ok"))
        self.txt_message = QtGui.QTextEdit(Form)
        self.txt_message.setGeometry(QtCore.QRect(20, 20, 331, 71))
        self.txt_message.setObjectName(_fromUtf8("txt_message"))
        self.pushButton_2 = QtGui.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(20, 100, 75, 23))
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))

        self.retranslateUi(Form)
        QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txt_message.selectAll)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.btn_ok.setText(_translate("Form", "OK", None))
        self.pushButton_2.setText(_translate("Form", "Select", None))

4. 実行スクリプトの作成

アプリケーションを実行する スクリプトを作成する。main.py とでもして、プロジェクト直下に作成すると、以下のような構成になる。

winpy15

上記で作成したUIを呼び出し、処理をバインドするコードを記述する。

構成に工夫の余地はあるが、Qt Desinger で作成した、UIを利用する Formを宣言することで、見た目と処理コードが分離(ボタンを押下したときの処理を、btn_ok_clicked() に記述し、初期化時にバインド)でき、継続的にUIを変更するサイクルも整った。

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from ui import first_form

class MyForm(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = first_form.Ui_Form()
        self.ui.setupUi(self)
        
        QtCore.QObject.connect(self.ui.btn_ok,QtCore.SIGNAL("clicked()"), self.btn_ok_cliked)

    def btn_ok_cliked(self):
        print type(self.ui)
        self.ui.txt_message.setText("Hello, Qt")
        
def run_app():
    app = QtGui.QApplication(sys.argv)
    form = MyForm()
    form.show()
    sys.exit(app.exec_())
    
if __name__ == '__main__':
    run_app()

5.実行

実行すると、ダイアログが立ち上がり、OKボタンを押下で、メッセージが表示され、Select ボタンで、メッセージを全選択されることが確認できた!!!

winpy13

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です