PyQt5入門(1)

#はじめに

　PyQt5の日本語ドキュメントが少なかったので、[僕が欲しい情報がいい感じにまとまった英語のドキュメント](https://pythonspot.com/pyqt5/)を翻訳しました。
#PyQt5とは
　PyQt5はGUIを作るためのモジュールだ。一つ前のPyQt4と下位互換性はない。
　使用するにはPython 2.6以上が必要なので、次のコマンドを叩いて確認する。

```console
$ python --version
```
Python3の場合は

```console
$ python3 --version
```
#PyQt5 window
　Linuxの場合は、次のコマンドを入力するとPyQt5をインストールできる。

```console
$ sudo apt-get install python3-pyqt5
```
　WindowsまたはmacOSの場合は、[ここ](https://www.riverbankcomputing.com/software/pyqt/download5
 )からインストールできる。
　インストールしたら、次のコードでPyQt5のウィンドウを作ることができる。

```python3:pyqt5.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon

 class App(QWidget):
 
 	def __init__(self):
		super().__init__()
		self.title = "PyQt5 simple window - pythonspot.com"
		self.left = 10
		self.top = 10
		self.width = 640
		self.height = 480
		self.initUI()
 
	def initUI(self):
		self.setWindowTitle(self.title)
		self.setGeometry(self.left, self.top, self.width, self.height)
		self.show()
 
if __name__ == "__main__":
	app = QApplication(sys.argv)
	ex = App()
	sys.exit(app.exec_())
```
　setGeometry(left, top, width, height)を使ってウィンドウサイズを設定する。

- left:モニターの左端からウィンドウの左上までの距離を指定。
- top：モニターの上端からウィンドウの左上までの距離を指定。
- width：ウィンドウの幅を指定。
- height：ウィンドウの高さを指定。

　最後にshow()が呼び出されるとウィンドウが表示される。
#PyQt5 statusbar
　PyQt5はステータスバー(メッセージ的な)をサポートしている。追加するには以下の行を書く。

```python3
self.statusBar().showMessage("Message in statusbar.")
```
　上記の例では、メインウィンドウ(QMainWindow)にステータスバーを追加している。以下はそれを使った例。

```python3:pyqt5.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from PyQt5.QtGui import QIcon
 
class App(QMainWindow):
 
	def __init__(self):
		super().__init__()
		self.title = "PyQt5 status bar example - pythonspot.com"
		self.left = 10
		self.top = 10
		self.width = 640
		self.height = 480
		self.initUI()
 
	def initUI(self):
		self.setWindowTitle(self.title)
		self.setGeometry(self.left, self.top, self.width, self.height)
		self.statusBar().showMessage("Message in statusbar.")
		self.show()
 
if __name__ == "__main__":
	app = QApplication(sys.argv)
	ex = App()
	sys.exit(app.exec_())
```
#PyQt5 buttons
　PyQt5はQPushButtonを使ったボタンをサポートしている。QPushButtonはPyQt5.QtWidgets内にあり、QPushButtonコンストラクタを呼び出すことで作成できる。引数として表示するテキストを指定できる。
　まず、以下のコードでQPushButtonなどを読み込む。

```python3
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import pyqtSlot
``` 
　initUI()に以下のコードを追加する。

```python3
button = QPushButton("PyQt5 button", self)
button.setToolTip("This is an example button")
button.move(100,70)
```
　QPushButtonがウィジェットを作成し、その引数がボタンに表示されるテキストとなっている。
　setTookTipではユーザーがボタンにカーソルを当てた時に表示されるメッセージを指定する。
　最後にボタンは座標(x = 100, y = 70)へと移動される。
　ボタンをクリックした時に実行される関数は、次のように定義する。

```python3
@pyqtSlot()
#実行される関数
def on_click(self):
	print("PyQt5 button click")
```
　ボタンと関数を紐付けする。

```python3
button.clicked.connect(self.on_click)
```

　最終的なコードは以下のようになる。

```python3:pyqt5.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
 
class App(QWidget):
 
	def __init__(self):
		super().__init__()
		self.title = "PyQt5 button - pythonspot.com"
		self.left = 10
		self.top = 10
		self.width = 320
		self.height = 200
		self.initUI()
 
	def initUI(self):
		self.setWindowTitle(self.title)
		self.setGeometry(self.left, self.top, self.width, self.height)
 
		button = QPushButton("PyQt5 button", self)
		button.setToolTip("This is an example button")
		button.move(100,70) 
		button.clicked.connect(self.on_click)
 
		self.show()
 
	@pyqtSlot()
	def on_click(self):
		print("PyQt5 button click")
 
if __name__ == 
"__main__":
	app = QApplication(sys.argv)
	ex = App()
	sys.exit(app.exec_())
```
#PyQt5 signals and slots
　GUIアプリケーションは、CUIのそれとは違い「イベント駆動形」である。そのとき、ボタンをクリックしたりリスト内の項目を選択したりといったユーザーの行動はイベントと呼ばれる。イベントが発生した場合、各PyQt5ウィジェットは信号を発することができる。信号はスロットで行われる行動を実行しない。
　この例で考えてみる。

```python3
button.clicked.connect(self.slot_method)
```
　「ボタンがクリックされた」という信号が、アクション(スロット)に接続されている。この例では、信号が発生するとslot_methodが呼び出される。
　スロット関数または機能をウィジェットに接続するというこの原則は全てのウィジェットに適用され、

```python3
widget.signal.connect(slot_method)
```
　このように信号を明示的に定義することもできる。
　また、PyQt5はクリックだけでなく様々なタイプの信号をサポートしている。
 以下のコードは、ボタンをクリックするとアクション(スロット)を実行できる。

```python3:pyqt5.py
from PyQt5.QtWidgets import QApplication, QComboBox, QDialog,
		QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
		QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit,
		QVBoxLayout
 
import sys
 
class Dialog(QDialog):
 
	def slot_method(self):
        print("slot method called.")
 
	def __init__(self):
		super(Dialog, self).__init__()
 
		button=QPushButton("Click")
		button.clicked.connect(self.slot_method)
 
		mainLayout = QVBoxLayout()
		mainLayout.addWidget(button)
 
		self.setLayout(mainLayout)
		self.setWindowTitle("Button Example - pythonspot.com")
 
 
if __name__ == "__main__":
	app = QApplication(sys.argv)
	dialog = Dialog()
sys.exit(dialog.exec_())
```
#PyQt5 messagebox
　メッセージボックスを表示させるには、QMessageBoxをインポートする必要がある。

```python3
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
```
　以下のコードを実行すると、メッセージボックスを表示することができる。

```python3:pyqt5.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
 
class App(QWidget):
 
	def __init__(self):
		super().__init__()
		self.title = "PyQt5 messagebox - pythonspot.com"
		self.left = 10
		self.top = 10
		self.width = 320
		self.height = 200
		self.initUI()
 
	def initUI(self):
		self.setWindowTitle(self.title)
		self.setGeometry(self.left, self.top, self.width, self.height)
 
		buttonReply = QMessageBox.question(self, "PyQt5 message", "Do you like PyQt5?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
		if buttonReply == QMessageBox.Yes:
			print("Yes clicked.")
		else:
			print("No clicked.")
 
		self.show()
 
if __name__ == "__main__":
	app = QApplication(sys.argv)
	ex = App()
	sys.exit(app.exec_())
```
　メッセージボックス用のボタンとしてQMessageBox.YesとQMessageBox.Noを使用しているが、他のオプションも簡単に設定できる。

```python3
QMessageBox.Cancel
QMessageBox.Ok	
QMessageBox.Help
QMessageBox.Open	
QMessageBox.Save	
QMessageBox.SaveAll
QMessageBox.Discard	
QMessageBox.Close	
QMessageBox.Apply
QMessageBox.Reset	
QMessageBox.Yes	
QMessageBox.YesToAll
QMessageBox.No	
QMessageBox.NoToAll	
QMessageBox.NoButton
QMessageBox.RestoreDefaults	
QMessageBox.Abort	
QMessageBox.Retry
QMessageBox.Ignore
```
#PyQt5 textbox
　PyQt5でテキストボックスを使うには、QLineEditを使う。それにはテキストボックスの初期値を指定するsetText()と、その値を取得するためのtext()がある。
　またresize(width, height)を使ってテキストボックスのサイズを設定することができる。位置はmove(x, y)かグリッドレイアウト(後述)を使用するかで設定できる。
　PyQt5のテキストボックスの作成はかなり簡単だ。

```python3
self.textbox = QLineEdit(self)
self.textbox.move(20, 20)
self.textbox.resize(280,40)
```
この例では、テキストボックス付きのウィンドウを作成する。

```python3:pyqt5.py
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
 
class App(QMainWindow):
 
	def __init__(self):
		super().__init__()
		self.title = "PyQt5 textbox - pythonspot.com"
		self.left = 10
		self.top = 10
		self.width = 400
		self.height = 140
		self.initUI()
 
	def initUI(self):
		self.setWindowTitle(self.title)
		self.setGeometry(self.left, self.top, self.width, self.height)
 
		# Create textbox
		self.textbox = QLineEdit(self)
		self.textbox.move(20, 20)
		self.textbox.resize(280,40)
 
		# Create a button in the window
		self.button = QPushButton("Show text", self)
		self.button.move(20,80)
 
		# connect button to function on_click
		self.button.clicked.connect(self.on_click)
		self.show()
 
	@pyqtSlot()
	def on_click(self):
		textboxValue = self.textbox.text()
		QMessageBox.question(self, "Message - pythonspot.com", "You typed: " + textboxValue, QMessageBox.Ok, QMessageBox.Ok)
		self.textbox.setText("")
 
 
if __name__ == "__main__":
	app = QApplication(sys.argv)
	ex = App()
	sys.exit(app.exec_())
```

#終わりに
今回はここまでです。見てくださってありがとうございました。次回は[こちら](https://qiita.com/itoppy18/items/94641421aeac2eafb5b1)から。