QT を Python から利用するためのライブラリには PyQt や PySide 等が存在します。PySide は元々 QT4 向けのライブラリでしたが、QT5 に対応するために新たに PySide2 が開発されました。PySide2 は Qt for Python
ともよばれています。
Q: PySide? Qt for Python? what is the name?
A: The name of the project is Qt for Python and the name of the module is PySide2.
Q: Why PySide2 and not just PySide?
A: Since PySide was developed for Qt4, when the port was made to support Qt5, the name was changed to PySide2 to infer that is was a newer version.
https://wiki.qt.io/Qt_for_Python
PySide2 について基本的な使い方を記載します。今回は VirtualBox と Vagrant で Debian9/stretch をインストールして利用することにします。
以下のコマンドで同期しつつ、X11 で動作確認します。
vagrant rsync
vagrant rsync-auto
必要なバージョンの python や qt5 等をインストールする必要があります。
pyenv を利用すると簡単です。今回は 2.7.15 を利用することにします。
pyenv global 2.7.15
PySide2 自体は pip でインストールできます。
pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.9/latest/ pyside2 --trusted-host download.qt.io
OpenGL 等が依存先としてまとめてインストールされます。環境によっては pyside2/wiki/Dependencies を参照して、不足しているパッケージを適宜追加でインストールします。
sudo apt-get install qt5-default
sudo apt-get install qttools5-dev-tools
DISPLAY
が利用できない場合は仮想ディスプレイを作成して利用します。
sample.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from PySide2.QtWidgets import QApplication, QLabel
def Main():
app = QApplication(argv)
label = QLabel("Hello World")
label.show()
exit(app.exec_())
if __name__ == '__main__':
Main()
古い環境の場合は必要な共有ライブラリが存在せずにエラーになります。新しい OS を利用するか、必要に応じてソースコードからビルドします。例えば以下のような libc のバージョンエラーが発生します。
$ python sample.py
Traceback (most recent call last):
File "sample.py", line 2, in <module>
from PySide2.QtWidgets import QApplication, QLabel
ImportError: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/username/.pyenv/versions/2.7.15/lib/python2.7/site-packages/PySide2/QtWidgets.so)
以下のようにソースコードからビルドして対応できます。
mkdir glibc_install
cd glibc_install/
wget http://ftp.gnu.org/gnu/glibc/glibc-2.14.1.tar.gz
tar zxvf glibc-2.14.1.tar.gz
cd glibc-2.14.1/
mkdir build
cd build/
../configure --prefix=/opt/glibc-2.14
make -j4
sudo make install
export LD_LIBRARY_PATH=/opt/glibc-2.14/lib
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from PySide2.QtWidgets import QApplication, QLabel
def Main():
app = QApplication(argv)
label = QLabel("<font color=red size=40>Hello World!</font>")
label.show()
exit(app.exec_())
if __name__ == '__main__':
Main()
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from PySide2.QtWidgets import QApplication
from PySide2.QtQuick import QQuickView
from PySide2.QtCore import QUrl
def Main():
app = QApplication(argv)
view = QQuickView()
url = QUrl("view.qml")
view.setSource(url)
view.show()
exit(app.exec_())
if __name__ == '__main__':
Main()
view.qml
import QtQuick 2.0
Rectangle {
width: 200
height: 200
color: "green"
Text {
text: "Hello World"
anchors.centerIn: parent
}
}
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from PySide2.QtWidgets import QApplication, QMessageBox
def Main():
app = QApplication(argv)
msg_box = QMessageBox()
msg_box.setText("Hello World!")
msg_box.show()
exit(app.exec_())
if __name__ == '__main__':
Main()
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from PySide2.QtWidgets import QApplication, QPushButton
def f():
print("clicked!")
def Main():
app = QApplication(argv)
# push 時に関数を実行
button = QPushButton("Click me")
button.clicked.connect(f)
buttonExit = QPushButton("Exit")
buttonExit.clicked.connect(app.exit)
button.show()
buttonExit.show()
exit(app.exec_())
if __name__ == '__main__':
Main()
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from random import choice
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayout, QApplication
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
self.nums = ["1", "2", "3"]
# ラベルの作成
self.text = QLabel("0")
self.text.setAlignment(Qt.AlignCenter)
# push ボタンの作成
self.button = QPushButton("Click me!")
self.button.clicked.connect(self.f)
# ラベルとボタンを格納する箱となるレイアウトの作成
self.layout = QVBoxLayout()
self.layout.addWidget(self.text)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
def f(self):
self.text.setText(choice(self.nums))
def Main():
app = QApplication(argv)
widget = MyWidget()
widget.show()
exit(app.exec_())
if __name__ == '__main__':
Main()
#!/usr/bin/python
# -*- coding: utf-8 -*-
from sys import exit, argv
from PySide2.QtWidgets import QLineEdit, QPushButton, QApplication, QVBoxLayout, QDialog
class MyForm(QDialog):
def __init__(self):
super(MyForm, self).__init__()
self.setWindowTitle("My Form")
# 入力フォーム、ボタン
self.edit = QLineEdit("xxxx")
self.button = QPushButton("yyyy")
self.button.clicked.connect(self.f)
# レイアウト
layout = QVBoxLayout()
layout.addWidget(self.edit)
layout.addWidget(self.button)
self.setLayout(layout)
def f(self):
print ("Hello %s" % self.edit.text())
def Main():
app = QApplication(argv)
form = MyForm()
form.show()
exit(app.exec_())
if __name__ == '__main__':
Main()