今回はウィジェットのカスタマイズです。
カスタマイズするウィジェットを継承したクラスを作り、カスタマイズ部分を実装してみます。
空を飛べないモンティ・パイソン
Pythonのお勉強メモみたいなもの
2015/04/28
PyQt5を使う (QDialogを継承する)
今回はQDialogクラスを継承したクラスによるダイアログの表示です。
ちょっと長いですが、実行結果はこんな感じになります。
QDialogを継承したクラス(FindDialog)のコンストラクタで各ウィジェットの初期化を行いますが、ウィジェットをレイアウトするためにQHBoxLayoutとQVBoxLayoutを使用します。
QHBoxLayoutは登録されたウィジェットを横に配置するウィジェット、QVBoxLayoutは登録されたウィジェットを縦に配置するウィジェットです。
CloseボタンのclickedシグナルにはQDialogのcloseメソッドを、FindボタンのclickedシグナルにはfindClickedメソッド、テキストボックのtextChangedsシグナルにはenableFindButtonメソッドを接続しています。
そして、実際にFindボタンがクリックされた時の処理するためのfindNextとfindPreviousのインスタンス変数をpyqtSignalで定義します。
Findボタンクリック時、"Search backword"チェックボックの値によって、findNextかfindPreviousに接続されたスロットを実行(emit)するようにしています。
作成したFindDialogクラスはインスタンス化し、findNextとfindPreviousのconnectを行う必要があります。
import sys
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtWidgets import QLabel, QLineEdit, QCheckBox, QPushButton, QHBoxLayout, QVBoxLayout
class FindDialog(QDialog):
    findPrevious = pyqtSignal(str, int)
    findNext = pyqtSignal(str, int)
    def __init__(self, parent=None):
        super(FindDialog, self).__init__(parent)
        self.label = QLabel(self.tr('Find &what'))
        self.lineEdit = QLineEdit()
        self.label.setBuddy(self.lineEdit)
        self.caseCheckBox = QCheckBox(self.tr('Match &case'))
        self.backwordCheckBox = QCheckBox(self.tr('Search &backword'))
        self.findButton= QPushButton(self.tr('&Find'))
        self.findButton.setDefault(True)
        self.findButton.setEnabled(False)
        self.closeButton = QPushButton(self.tr('Close'))
        self.lineEdit.textChanged[str].connect(self.enableFindButton)
        self.findButton.clicked.connect(self.findClicked)
        self.closeButton.clicked.connect(self.close)
        self.topLeftLayout = QHBoxLayout()
        self.topLeftLayout.addWidget(self.label)
        self.topLeftLayout.addWidget(self.lineEdit)
        self.leftLayout = QVBoxLayout()
        self.leftLayout.addLayout(self.topLeftLayout)
        self.leftLayout.addWidget(self.caseCheckBox)
        self.leftLayout.addWidget(self.backwordCheckBox)
        self.rightLayout = QVBoxLayout()
        self.rightLayout.addWidget(self.findButton)
        self.rightLayout.addWidget(self.closeButton)
        self.rightLayout.addStretch()
        self.mainLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.leftLayout)
        self.mainLayout.addLayout(self.rightLayout)
        self.setLayout(self.mainLayout)
        self.setWindowTitle(self.tr('Find'))
        self.setFixedHeight(self.sizeHint().height())
    def findClicked(self):
        text = self.lineEdit.text()
        cs = Qt.CaseSensitive if self.caseCheckBox.isChecked() == True else Qt.CaseInsensitive
        if self.backwordCheckBox.isChecked() == True:
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)
    def enableFindButton(self, text):
        self.findButton.setEnabled(len(text) != 0)
def findNext(text, cs):
    print('Find Next ! text={0} cs={1}'.format(text, cs))
def findPrevious(text, cs):
    print('Find Previous ! text={0} cs={1}'.format(text, cs))
if __name__ == '__main__':
    app = QApplication(sys.argv)
    find = FindDialog()
    find.findNext.connect(findNext)
    find.findPrevious.connect(findPrevious)
    find.show()
    sys.exit(app.exec_())
ちょっと長いですが、実行結果はこんな感じになります。
QDialogを継承したクラス(FindDialog)のコンストラクタで各ウィジェットの初期化を行いますが、ウィジェットをレイアウトするためにQHBoxLayoutとQVBoxLayoutを使用します。
QHBoxLayoutは登録されたウィジェットを横に配置するウィジェット、QVBoxLayoutは登録されたウィジェットを縦に配置するウィジェットです。
CloseボタンのclickedシグナルにはQDialogのcloseメソッドを、FindボタンのclickedシグナルにはfindClickedメソッド、テキストボックのtextChangedsシグナルにはenableFindButtonメソッドを接続しています。
そして、実際にFindボタンがクリックされた時の処理するためのfindNextとfindPreviousのインスタンス変数をpyqtSignalで定義します。
Findボタンクリック時、"Search backword"チェックボックの値によって、findNextかfindPreviousに接続されたスロットを実行(emit)するようにしています。
作成したFindDialogクラスはインスタンス化し、findNextとfindPreviousのconnectを行う必要があります。
2015/04/27
2015/04/25
2015/04/24
Hello PyQt5
新しい言語を勉強する時は、”Hello World”を出力するのがお約束になっていますが、入門Qt4プログラミング(オライリー・ジャパン)も同様のようです。
3~4行目でQApplicationとQLabelをインポートしていますが、どうやらQt4とQt5はパッケージの構成が異なるようです。
7行目、QApplicationをインスタンス化します。
ここでは、コマンドライン引数が必要になるため、パラメータとして sys.argv を指定します。
9行目、QLabel をインスタンス化します。
QLabel は、テキストまたはイメージの表示を行うウィジェットです。
Qtではユーザが操作するユーザインターフェース要素のことをウィジェットと言うんだそうです。
(Unixもそうらしいです、勉強になりますね♪)
QLabelをインスタンス化する際のパラメータとして’Hello Qt5!’を指定しています。
これが表示する文字列ですね。
10行目、ここでラベルを表示状態にします。
Qtではウィジェットは常に非表示の状態で生成されるので、インスタンス化が終わったら表示させます。
12行目、制御をQtに渡します。
これによってアプリはイベントループに入り、ユーザからの操作を待つということですね。
ウィジェットは単体でもウィンドウとして機能するようで、今回のようにラベルだけをウィンドウとしてアプリ実行することができます。
なんて便利なんでしょう♪
上のサンプルでは、QLabelのインスタンス化時に’Hello Qt5!’という文字列を指定していますが、HTMLも指定可能だそうです。
画像も出力させるには以下のようになります。
QLabelウィジェットを引数なしでインスタンス化し、setPixmapメソッドで画像データを指定することで可能になります。
GUIがお手軽にできていいですね♪
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLabel
if __name__ == '__main__':
    app = QApplication(sys.argv)
    label = QLabel('Hello Qt5!')
    label.show()
    sys.exit(app.exec_())
3~4行目でQApplicationとQLabelをインポートしていますが、どうやらQt4とQt5はパッケージの構成が異なるようです。
7行目、QApplicationをインスタンス化します。
ここでは、コマンドライン引数が必要になるため、パラメータとして sys.argv を指定します。
9行目、QLabel をインスタンス化します。
QLabel は、テキストまたはイメージの表示を行うウィジェットです。
Qtではユーザが操作するユーザインターフェース要素のことをウィジェットと言うんだそうです。
(Unixもそうらしいです、勉強になりますね♪)
QLabelをインスタンス化する際のパラメータとして’Hello Qt5!’を指定しています。
これが表示する文字列ですね。
10行目、ここでラベルを表示状態にします。
Qtではウィジェットは常に非表示の状態で生成されるので、インスタンス化が終わったら表示させます。
12行目、制御をQtに渡します。
これによってアプリはイベントループに入り、ユーザからの操作を待つということですね。
ウィジェットは単体でもウィンドウとして機能するようで、今回のようにラベルだけをウィンドウとしてアプリ実行することができます。
なんて便利なんでしょう♪
上のサンプルでは、QLabelのインスタンス化時に’Hello Qt5!’という文字列を指定していますが、HTMLも指定可能だそうです。
    label = QLabel('<h2><i>Hello</i> <span style="color: red;">Qt5!</span></h2>')
画像も出力させるには以下のようになります。
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLabel
from PyQt5.QtGui import QPixmap
if __name__ == '__main__':
    app = QApplication(sys.argv)
    label = QLabel()
    label.setPixmap(QPixmap("[画像ファイルパス]"))
    label.show()
    sys.exit(app.exec_())
QLabelウィジェットを引数なしでインスタンス化し、setPixmapメソッドで画像データを指定することで可能になります。
GUIがお手軽にできていいですね♪
2015/04/23
登録:
コメント (Atom)



