PyQtの基礎 - 画面
概要
画面の表示
まず、PyQtで基本となるものは、画面を表示することである。
以下のサンプルコードでは、QWidget
クラスを使用して画面のみを表示している。
<syntaxhighlight lang="python"> # - * - coding: utf8 - * - import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * # QWidgetクラスの使用 class MyWindow(QWidget): def __init__(self, parent=None): super(MyWindow, self).__init__(parent) self.title = "ウィンドウのタイトル" self.width = 500 self.height = 400 self.setWindowTitle(self.title) self.setGeometry(0, 0, self.width, self.height) self.show() def main(): App = QApplication(sys.argv) Window = MyWindow() sys.exit(App.exec_()) if __name__ == "__main__": main() </source>
ステータスバーの表示
ここでは、画面にステータスバーを表示する方法を記載する。
ステータスバーには、現在の画面内の情報等を表示することが可能である。
上記のセクションでは、QWidget
クラスを継承したMyWindowクラスを作成して画面を表示しているが、
ステータスバーを表示するには、QMainWindow
クラスを継承して画面を作成する必要がある。
QWidget
クラスやQDialog
クラスを使用して画面を作成することもできるが、
メイン画面においてはQMainWindow
クラスを使用することを推奨する。
それは、QMainWindow
クラスは、以下に示すメイン画面を作成するための機能を提供しているからである。
- メニューバー
- ツールバー
- ドックウィジェット
- 中央ウィジェット
- ステータスバー
以下のサンプルコードでは、ステータスバーを表示している。
<syntaxhighlight lang="python"> # - * - coding: utf8 - * - import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * # QMainWindowクラスの使用 class MyWindow(QMainWindow): def __init__(self, parent=None): super(MyWindow, self).__init__(parent) self.title = "ウィンドウのタイトル" self.width = 500 self.height = 400 self.setWindowTitle(self.title) self.setGeometry(0, 0, self.width, self.height) self.statusBar().showMessage('ステータスバーの表示') self.show() def main(): App = QApplication(sys.argv) Window = MyWindow() sys.exit(App.exec_()) if __name__ == "__main__": main() </source>
以下のサンプルコードでは、ステータスバーにデジタル時計を表示している。
<syntaxhighlight lang="python"> # - * - coding: utf8 - * - import sys import datetime # 時計を表示するために必要 from PyQt5.QtCore import * from PyQt5.QtWidgets import * # QMainWindowクラスの使用 class MyWindow(QMainWindow): def __init__(self, parent=None): super(MyWindow, self).__init__(parent) self.title = "ウィンドウのタイトル" self.width = 500 self.height = 400 self.setWindowTitle(self.title) self.setGeometry(0, 0, self.width, self.height) self.show() timer = QTimer(self) timer.timeout.connect(self.getDateTime) timer.start(1000) # 1000ミリ秒 def getDateTime(self): dt = datetime.datetime.today() dt_str = dt.strftime("%Y年%m月%d日 %H時%M分%S秒") self.statusBar().showMessage("ステータスバーの時計" + " " + dt_str) def main(): App = QApplication(sys.argv) Window = MyWindow() sys.exit(App.exec_()) if __name__ == "__main__": main() </source>
上記のサンプルコードでは、シグナルとスロットと呼ばれる機能を使用している。
オブジェクトは、何らかのイベントが生じた際にシグナルを発生させて、それをスロットの関数が受け取ることで画面上の情報を更新することができる。
ここでは、QTimerのインスタンスを生成した後、timeoutシグナルに対してgetDateTimeメソッドをスロットとして呼び出して、それらをconnectで結び付けている。
<syntaxhighlight lang="python"> timer = QTimer(self) timer.timeout.connect(self.getDateTime) timer.start(1000) </source>
メニューバーの表示
このセクションでは、メニューバーを表示する。
以下のサンプルコードでは、メニューバーと[ファイル]メニューおよび[終了]サブメニューを表示して、
[終了]サブメニューにソフトウェアを終了するメニューバーアクションを定義している。
<syntaxhighlight lang="python"> # - * - coding: utf8 - * - import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * # QMainWindowクラスの使用 class MyWindow(QMainWindow): def __init__(self, parent=None): super(MyWindow, self).__init__(parent) self.title = "ウィンドウのタイトル" self.width = 500 self.height = 400 # メニューバーの定義 exitAction = QAction('&終了', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('終了する') exitAction.triggered.connect(qApp.quit) # メニューバーアクションの追加 menubar = self.menuBar() fileMenu = menubar.addMenu('&ファイル') fileMenu.addAction(exitAction) self.setWindowTitle(self.title) self.setGeometry(0, 0, self.width, self.height) # ステータスバー self.statusBar()
self.show() def main(): App = QApplication(sys.argv) Window = MyWindow() sys.exit(App.exec_()) if __name__ == "__main__": main() </source>
レイアウト
PyQtのレイアウトは、QHBoxとQVBoxの2種類(縦(horizon)と横(vertical))が存在する。
指定が無い場合、QHBox(縦のレイアウト)が自動的に配置される。
以下のサンプルコードにおいて、13行目のself.upper.stateChanged.connect(self.uppercase)
では、
connect
により、"Upper"チェックボックスにチェックが入っている時、uppercase
関数にコネクトする。
addWiget
関数では、upper_aチェックボックスとupper_bチェックボックスを指定している。
また、addWiget
関数では、vertical
を指定している。
vertical
にはQVBoxLayout(縦のレイアウト)
を指定しているので、チェックボックスが縦に並ぶ。
グループ化されていないので、複数のチェックボックスを選択することができる。
36行目において、チェックボックスにチェックが入力されていない時は、
removeWiget
関数により、チェックを入力するたびにチェックボックスが追加される現象を防いでいる。
<syntaxhighlight lang="python"> import sys import sip from PyQt5.QtCore import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # 上のチェックボックス self.upper = QCheckBox('Upper', self) self.upper.move(100, 30) self.upper.stateChanged.connect(self.uppercase) # 横のレイアウト self.horizon = QHBoxLayout() # 縦のレイアウト self.vertical = QVBoxLayout() self.horizon.addLayout(self.vertical) self.setLayout(self.horizon) self.setGeometry(300, 50, 400, 350) self.setWindowTitle('QCheckBox') def uppercase(self): if(self.upper.isChecked()): self.upper_a = QCheckBox('A', self) self.vertical.addWidget(self.upper_a) self.upper_b = QCheckBox('B', self) self.vertical.addWidget(self.upper_b) else: self.vertical.removeWidget(self.upper_a) self.vertical.removeWidget(self.upper_b) if __name__ == '__main__': App = QApplication(sys.argv) Window = MainWindow() Window.show() sys.exit(App.exec_()) </source>
以下のサンプルコードでは、QPushButtonを追加して、ボタンの押下時のイベントをoutput関数にコネクトしている。
output関数では、各チェックボックスにチェックが入力されている時、それぞれ文字Aと文字Bをコンソールに出力している。
<syntaxhighlight lang="python"> import sys import sip from PyQt5.QtCore import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # 一つ目のチェックボックス self.upper = QCheckBox('Upper', self) self.upper.move(100, 30) self.upper.stateChanged.connect(self.uppercase) # 横のレイアウト self.horizon = QHBoxLayout() # 縦のレイアウト self.vertical = QVBoxLayout() # ボタンの追加 self.button = QPushButton('コンソールに出力', self) self.button.clicked.connect(self.output) self.horizon.addLayout(self.vertical) self.setLayout(self.horizon) self.setGeometry(300, 50, 400, 350) self.setWindowTitle('QCheckBox') def uppercase(self): if(self.upper.isChecked()): self.upper_a = QCheckBox('A', self) self.vertical.addWidget(self.upper_a) self.upper_b = QCheckBox('B', self) self.vertical.addWidget(self.upper_b) else: self.vertical.removeWidget(self.upper_a) self.vertical.removeWidget(self.upper_b) def output(self): outputs = [] if(self.upper_a.isChecked()): outputs.append("A") if(self.upper_b.isChecked()): outputs.append("B") for output in outputs: print(output) if __name__ == '__main__': App = QApplication(sys.argv) Window = MainWindow() Window.show() sys.exit(App.exec_()) </source>