PyQt 5、最初のウィンドウ


0.はじめに
Qtは1991年にQt Companyが開発したプラットフォーム間C++グラフィックユーザーインタフェースアプリケーション開発フレームワークであり、現在デスクトップアプリケーションを開発する主流のフレームワークである.PyQt 5はQtフレームワークのPythonバインディングであり,SIPバインディングジェネレータを用いて構築される.なお、Qtの大部分のモジュールはLGPLプロトコルであるが、PyQt 5はGPL 3である.
学習を開始する前に、まずインストールPyQt 5モジュールをインストールします.
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple PyQt5

PyQtのドキュメントは完全ではありません.PySide 2のドキュメントを参照してください.https://doc.qt.io/qtforpython/、PySide 2はQt公式のPythonバインドバージョンです.
1.最初のウィンドウ
まず簡単なウィンドウを実現し、独自のウィンドウクラスを派生します.
import sys
from PyQt5.QtWidgets import QApplication,QWidget

if __name__=="__main__":
    #  Qt          Application  
    #     exec_()      ,               、     。
    #sys.argv       ,        。
    app=QApplication(sys.argv)

    #QWidget QtWidget       
    w=QWidget()
    #      
    w.resize(300,200)
    #      
    w.setWindowTitle("Hello World")
    #    
    w.show()

    #  exit()             
    #  exec_()      ,  exec   Python   ,   exec_()  
    sys.exit(app.exec_())

2.信号スロットの簡単な説明
Qtでは,信号とスロットを用い,これもQtの主な特性であるコールバック技術に代わる方法がある.特定のイベントが発生すると対応する信号がトリガーされ、QObjectオブジェクトには関連する信号スロットを保存するキューがあり、信号がトリガーされると自動的にスロット関数が呼び出されます.Qtのクラスには多くの事前定義された信号があり、実際に応用する際にも独自の信号を定義する必要があり、connect関数によって信号を他の信号やスロット関数に関連付けることができ、スロット関数はQt 5で任意の呼び出し可能なオブジェクトであることができる.信号とスロットメカニズムはタイプが安全です.信号のパラメータリストはスロット関数のパラメータリストと一致しなければなりません(スロット関数のパラメータ個数は信号パラメータ個数より少ないことができます).詳細はドキュメントを参照してください.https://doc.qt.io/qt-5.12/signalsandslots.html
次に、信号スロットをコードで示し、ウィンドウを閉じるボタンとテストを印刷するボタンを2つ作成します.
import sys
#qApp QApplication     , QCoreApplication::instance
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,qApp

#  QWidget,      
class MyWidget(QWidget):
    def __init__(self, parent=None):
        #      
        super().__init__(parent=parent)
        self.setWindowTitle("Hello World")
        self.resize(500,400)

        #          ,Qt   parent            
        vlayout=QVBoxLayout(self)
        #    
        self.closeBtn=QPushButton("Close",self)
        #       
        vlayout.addWidget(self.closeBtn)
        #     Widget ,     ,  self    
        #self.setLayout(vlayout)

        #      ,  app     
        #              
        self.closeBtn.clicked.connect(qApp.quit)

        #     
        self.printBtn=QPushButton("Print",self)
        vlayout.addWidget(self.printBtn)
        #lambda       ,          
        self.printBtn.setCheckable(True)
        self.printBtn.clicked.connect(lambda isCheck:print(isCheck))

if __name__=="__main__":
    app=QApplication(sys.argv)

    w=MyWidget()
    w.show()

    sys.exit(app.exec_())

3.イベントの概要
Qtでは、イベントは抽象的なQEventクラスから派生したオブジェクトであり、アプリケーション内またはアプリケーションが理解する必要がある外部アクティビティによって発生したことを表す.イベントはQObjectサブクラスの任意のインスタンスによって受信および処理することができるが、これらは特にウィジェットに関連する.
イベントの作成方法と割り当て方法によって、イベントは3つに分類されます.
  • ウィンドウシステムは、自発的イベント(Spontaneous events)を生成します.システムキューに格納され、イベントループによって次々と処理されます.
  • パブリッシュイベント(Posted events)は、Qtまたはアプリケーションによって生成される.Qtによってキュー化され、イベントループによって処理されます.
  • 送信イベント(Sent events)は、Qtまたはアプリケーションによって生成されるが、ターゲットオブジェクトに直接送信される.

  • QAPplicationのexecを呼び出すと()関数の場合、アプリケーションはQtのイベントループに入ります.
    Qt内のイベントは、5つの異なるレベルで処理できます.
  • 特定のイベントハンドラを再実装する.(paintイベントのpaintEvent()など)
  • QObjectのevent()関数を再実装します.
  • QObjectにイベントフィルタをインストールします.
  • qAppにイベントフィルタをインストールします.(qAppはQAPplicationの一例である)
  • QAPplicationのnotify()関数を再実装します.

  • 詳細は、ドキュメントを参照してください.https://doc.qt.io/qt-5.12/eventsandfilters.html
    次に、イベントハンドラがどのように書かれているかをコードで示し、resizeEventがウィンドウサイズを変更したハンドラに印刷文を追加します.
    import sys
    from PyQt5.QtGui import QResizeEvent
    from PyQt5.QtWidgets import QApplication,QWidget
    
    #  QWidget,  resize           
    class MyWidget(QWidget):
        def __init__(self, parent=None):
            #      
            super().__init__(parent=parent)
            self.setWindowTitle("Hello World")
            self.resize(500,400)
    
        def resizeEvent(self,event):
            #super().resizeEvent(event)
            #    
            print(event.size())
    
    if __name__=="__main__":
        app=QApplication(sys.argv)
    
        w=MyWidget()
        w.show()
    
        sys.exit(app.exec_())
    

    4.参考
    Qt信号スロットドキュメント:https://doc.qt.io/qt-5.12/signalsandslots.html
    Qtイベントシステムドキュメント:https://doc.qt.io/qt-5.12/eventsandfilters.html
    Qtイベント処理ドキュメント:https://doc.qt.io/archives/qq/qq11-events.html
    PyQt 5ドキュメント:https://www.riverbankcomputing.com/static/Docs/PyQt5/introduction.html
    PyQt 5チュートリアル:http://code.py40.com/1961.html