LoginSignup
0

posted at

updated at

PyQt5勉強③

はじめに

前回から、QtDesignerを使ってGUIを作成しています。

今回は、部品それぞれにイベントを設定していきます。

前回の復習

前回までは、以下のようなフォームを作成してきました。

QtDesigner1

今回もこのフォームをそのまま使います。

Signals & Slotsとは

Signals & Slotsは、Qt Frameworkで使われる、イベントの発生と処理を簡単にするためのメカニズムです。
QtDesignerのSignals & Slotsを利用すると、GUIアプリケーションの作成が簡単になります。

Signalsは、イベントを発生させるオブジェクトが送信するシグナルであり、Slotsは、イベントを受信して処理するオブジェクトが持つスロットです。
これらのシグナルとスロットを接続することで、シグナルが発生したときに、スロットで定義された処理が自動的に呼び出されます。

QtDesignerのSignals & Slotsは、ユーザーインターフェースを設計する際に非常に便利であり、コードを書くことなくGUIアプリケーションを作成することができます。

Signals & Slotsの設定

現時点での、オブジェクトインスペクタとシグナル/スロットエディタを示します。
オブジェクト名は一部変更しています。

SignalsSlots① SignalsSlots②

シグナル/スロットエディタで、以下のように設定します。
SignalsSlots③

PushButtonの"Submit"に"clicked"シグナルを設定します。
次にLineEditの"EmailAdress"と"Password"に"clear"スロットを設定します。

この状態で.uiファイルを保存し、"pyuic5"コマンドを実行します。
「Submitボタンを押すと、フォームに入力していた内容がクリアになる」という処理を、一切コードを書かずに行うことができます。

sample1.py
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'form3.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(260, 230)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(10, 10, 71, 16))
        self.label_2.setObjectName("label_2")
        self.EmailAdress = QtWidgets.QLineEdit(self.centralwidget)
        self.EmailAdress.setGeometry(QtCore.QRect(10, 30, 221, 20))
        self.EmailAdress.setObjectName("EmailAdress")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(10, 60, 241, 16))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(10, 90, 71, 16))
        self.label_4.setObjectName("label_4")
        self.Password = QtWidgets.QLineEdit(self.centralwidget)
        self.Password.setGeometry(QtCore.QRect(10, 110, 221, 20))
        self.Password.setEchoMode(QtWidgets.QLineEdit.Password)
        self.Password.setObjectName("Password")
        self.Submit = QtWidgets.QPushButton(self.centralwidget)
        self.Submit.setGeometry(QtCore.QRect(10, 160, 75, 23))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.Submit.setFont(font)
        self.Submit.setStyleSheet("background-color:#D3DEF1;\n"
"")
        self.Submit.setObjectName("Submit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 260, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        # ボタンがクリックされた時の処理を設定する
        self.Submit.clicked.connect(self.EmailAdress.clear) # type: ignore
        self.Submit.clicked.connect(self.Password.clear) # type: ignore

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_2.setText(_translate("MainWindow", "Email Adress"))
        self.label_3.setText(_translate("MainWindow", "We\'ll never share your email with anyone else."))
        self.label_4.setText(_translate("MainWindow", "Password"))
        self.Submit.setText(_translate("MainWindow", "Submit"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

SignalsSlots④

よく使われるSignal

  1. clicked()
    QPushButtonやQToolButtonなど、ボタンがクリックされたときに発行されるSignalです。
    これに紐づけたSlotを定義することで、ボタンがクリックされたときに任意の処理を行うことができます。

  2. valueChanged()
    QSpinBoxやQSliderなど、値が変更されたときに発行されるSignalです。
    これに紐づけたSlotを定義することで、値が変更されたときに任意の処理を行うことができます。

  3. textChanged()
    QLineEditなど、テキストが変更されたときに発行されるSignalです。
    これに紐づけたSlotを定義することで、テキストが変更されたときに任意の処理を行うことができます。

  4. currentIndexChanged()
    QComboBoxやQTabWidgetなど、現在選択されているアイテムが変更されたときに発行されるSignalです。
    これに紐づけたSlotを定義することで、アイテムが変更されたときに任意の処理を行うことができます。

  5. triggered()
    QActionやQShortcutなど、アクションがトリガーされたときに発行されるSignalです。
    これに紐づけたSlotを定義することで、アクションがトリガーされたときに任意の処理を行うことができます。

  6. customSignal
    Qtでは、自分でSignalを定義することもできます。これを使うことで、独自のイベントを発行することができます。

新しいウィンドウの表示

Signals & Slotsは、Qtの強力な機能の1つですが、すべてのことをカバーするわけではありません。
特に、2つ以上のウィンドウを扱う場合には、Pythonコードを使用して直接制御する必要がある場合があります。

WarningとInformationの表示

今回は、EmailAdressとPasswordのいづれかが入力されていない状態でSubmitボタンが押されたときはWarning
両方が一文字でも入力されたことが確認できた時はInformationを表示するようにします。

"pyuic5"コマンドを実行します。

sample2.py
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'form.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(260, 210)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(10, 10, 71, 16))
        self.label_2.setObjectName("label_2")
        self.EmailAdress = QtWidgets.QLineEdit(self.centralwidget)
        self.EmailAdress.setGeometry(QtCore.QRect(10, 30, 221, 20))
        self.EmailAdress.setObjectName("EmailAdress")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(10, 60, 241, 16))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(10, 90, 71, 16))
        self.label_4.setObjectName("label_4")
        self.Password = QtWidgets.QLineEdit(self.centralwidget)
        self.Password.setGeometry(QtCore.QRect(10, 110, 221, 20))
        self.Password.setEchoMode(QtWidgets.QLineEdit.Password)
        self.Password.setObjectName("Password")
        self.Submit = QtWidgets.QPushButton(self.centralwidget)
        self.Submit.setGeometry(QtCore.QRect(10, 160, 75, 23))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.Submit.setFont(font)
        self.Submit.setStyleSheet("background-color:#D3DEF1;\n""
")
        self.Submit.setObjectName("Submit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        # ボタンがクリックされた時の処理を設定する
        # 変更後
        self.Submit.clicked.connect(self.handle_submit) # type: ignore

        """ 
        # 変更前
        self.Submit.clicked.connect(self.EmailAdress.clear) # type: ignore
        self.Submit.clicked.connect(self.Password.clear) # type: ignore
        """
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_2.setText(_translate("MainWindow", "Email Adress"))
        self.label_3.setText(_translate("MainWindow", "We\'ll never share your email with anyone else."))
        self.label_4.setText(_translate("MainWindow", "Password"))
        self.Submit.setText(_translate("MainWindow", "Submit"))

    # ボタンがクリックされた時の処理を設定する
    def handle_submit(self):
        # Emailアドレスとパスワードを取得する
        email = self.EmailAdress.text()
        password = self.Password.text()

        # Emailアドレスとパスワードがどちらも入力されているか確認する
        if not email or not password:
            # 入力が不完全であることをユーザーに知らせる
            QtWidgets.QMessageBox.warning(None, "Warning", "Please enter both email address and password.")
        else:
            # 入力が完全であることをユーザーに知らせる
            QtWidgets.QMessageBox.information(None, "Information", "Sending information...")

        # Emailアドレスとパスワードをクリアする
        self.EmailAdress.clear()
        self.Password.clear()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

このようにウィンドウを直接制御しました。以下のようなウィンドウが表示されるはずです。

Warning① Warning②
Information① Information②

最後に

これでQt Designerを使ってのGUI作成は終了です。
次回何やるかは未定です。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0