はじめに
前回から、QtDesignerを使ってGUIを作成しています。
今回は、部品それぞれにイベントを設定していきます。
前回の復習
前回までは、以下のようなフォームを作成してきました。
今回もこのフォームをそのまま使います。
Signals & Slotsとは
Signals & Slotsは、Qt Frameworkで使われる、イベントの発生と処理を簡単にするためのメカニズムです。
QtDesignerのSignals & Slotsを利用すると、GUIアプリケーションの作成が簡単になります。
Signalsは、イベントを発生させるオブジェクトが送信するシグナルであり、Slotsは、イベントを受信して処理するオブジェクトが持つスロットです。
これらのシグナルとスロットを接続することで、シグナルが発生したときに、スロットで定義された処理が自動的に呼び出されます。
QtDesignerのSignals & Slotsは、ユーザーインターフェースを設計する際に非常に便利であり、コードを書くことなくGUIアプリケーションを作成することができます。
Signals & Slotsの設定
現時点での、オブジェクトインスペクタとシグナル/スロットエディタを示します。
オブジェクト名は一部変更しています。
PushButtonの"Submit"に"clicked"シグナルを設定します。
次にLineEditの"EmailAdress"と"Password"に"clear"スロットを設定します。
この状態で.uiファイルを保存し、"pyuic5"コマンドを実行します。
「Submitボタンを押すと、フォームに入力していた内容がクリアになる」という処理を、一切コードを書かずに行うことができます。
# -*- 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_())
よく使われるSignal
-
clicked()
QPushButtonやQToolButtonなど、ボタンがクリックされたときに発行されるSignalです。
これに紐づけたSlotを定義することで、ボタンがクリックされたときに任意の処理を行うことができます。 -
valueChanged()
QSpinBoxやQSliderなど、値が変更されたときに発行されるSignalです。
これに紐づけたSlotを定義することで、値が変更されたときに任意の処理を行うことができます。 -
textChanged()
QLineEditなど、テキストが変更されたときに発行されるSignalです。
これに紐づけたSlotを定義することで、テキストが変更されたときに任意の処理を行うことができます。 -
currentIndexChanged()
QComboBoxやQTabWidgetなど、現在選択されているアイテムが変更されたときに発行されるSignalです。
これに紐づけたSlotを定義することで、アイテムが変更されたときに任意の処理を行うことができます。 -
triggered()
QActionやQShortcutなど、アクションがトリガーされたときに発行されるSignalです。
これに紐づけたSlotを定義することで、アクションがトリガーされたときに任意の処理を行うことができます。 -
customSignal
Qtでは、自分でSignalを定義することもできます。これを使うことで、独自のイベントを発行することができます。
新しいウィンドウの表示
Signals & Slotsは、Qtの強力な機能の1つですが、すべてのことをカバーするわけではありません。
特に、2つ以上のウィンドウを扱う場合には、Pythonコードを使用して直接制御する必要がある場合があります。
WarningとInformationの表示
今回は、EmailAdressとPasswordのいづれかが入力されていない状態でSubmitボタンが押されたときはWarning、
両方が一文字でも入力されたことが確認できた時はInformationを表示するようにします。
"pyuic5"コマンドを実行します。
# -*- 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_())
このようにウィンドウを直接制御しました。以下のようなウィンドウが表示されるはずです。
最後に
これでQt Designerを使ってのGUI作成は終了です。
次回は別軸で動いてきたfoliumと組み合わせていきます。
参考