LoginSignup
0

PyQt5勉強③

Last updated at Posted at 2023-03-17

はじめに

前回から、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作成は終了です。

次回は別軸で動いてきたfoliumと組み合わせていきます。

参考

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
  3. You can use dark theme
What you can do with signing up
0