SlideShare a Scribd company logo
1 of 72
PyQtではじめる
GUIプログラミング

            2011-08-27
     Python Conference JP 2011

              Ransui Iso
 Strategic Technology Group / X-Listing Co, Ltd.


                                       Copyright (c) 2011 Ransui Iso, All rights reserved.
おまえ誰よ?
               Ransui Iso (磯 蘭水)
               Work at X-Listing Co, Ltd.
               http://www.xlisting.co.jp/


Pythonは1998年から使っています。E-Commerceエンジンやサーチエンジンの開
発、Zopeを用いたWebサイト開発、その他色々を経て、今はネット広告配信シス
テムについての研究開発をしています。最近はCommon Lispでシステム開発をし
ていますが、Pythonもヘビーに使っています。



  http://www.facebook.com/ransui

  @ransui


                                  Copyright (c) 2011 Ransui Iso, All rights reserved.
今日お話する内容
●   QtとPyQtについて
●   開発環境を整える
●   HelloWorld
●   QApplication と Event Loop
●   SIGNALとSLOT
●   GUIアプリケーション開発の基礎
●   便利ツール : assistant, designer
●   Graphics, Multimedia, Web関連機能
●   さらに先へ行くために

                                  Copyright (c) 2011 Ransui Iso, All rights reserved.
対象とするレベル
●   Pythonプログラミングの経験
     –   午前中のセッション「Pythonチュートリアル」
     –   書籍「はじめてのPython」
     –   Python公式ドキュメント「Pythonチュートリアル」
         以上のいずれかをクリアしている方


●   GUIプログラミング経験
     –   基本的にGUIプログラミング経験が無い方を想定
     –   tkinter, wxPython, PyGtk等の経験者の方はPyQt独特の
         方法を学ぶ機会になるかと思いますが、多分ドキュメント読
         めば独学できる内容


                                 Copyright (c) 2011 Ransui Iso, All rights reserved.
その他注意点など
●   ハンズオンではありません
     –   セッション時間内での演習時間等は予定していません
     –   このスライドは自習時の参考にもなるように作っています


●   当日はご参加ありがとうございました
     –   サンプルコードは以下にあります。
     –   http://alpa.homeip.net/files/PyConJP2011­SampleCodes.zip



●   質問はfacebook上で
     –   twitterはあまり使っていないので、facebookのメッセージと
         かでコンタクトしてくれると反応するかもです。


                                                      Copyright (c) 2011 Ransui Iso, All rights reserved.
QtとPyQtについて
 Introduction of Qt and PyQt




                        Copyright (c) 2011 Ransui Iso, All rights reserved.
Qtについて
●   クロスプラットフォームのC++総合ライブラリ
     –   最初期はGUIツールキットとして作られていたが、すぐにC++の総
         合ライブラリに成長した
     –   Windows, MacOSX, X11を主要として複数のプラットフォームに
         対応している


●   ライセンス形態
     –   LGPL 2.1 + Commercial のデュアルライセンス


●   読み方
     –   「きゅーと」と読むらしい
     –   「きゅーてぃー」でもおおよそ通じると思われる


                                    Copyright (c) 2011 Ransui Iso, All rights reserved.
Qtを使っているもの
●   KDE
●   Google Earth
●   Picasa Client
●   VLC Media Player
●   Guitar Pro
●   Mathmatica
●   Skype


                       Copyright (c) 2011 Ransui Iso, All rights reserved.
Qtのモジュール群
●   総合ライブラリと呼ぶに相応しい充実度
     ●   QtCore          ●   QtScriptTools
     ●   QtGui           ●   QtSql
     ●   QtMultimedia    ●   QtSvg
     ●   QtNetwork       ●   QtWebKit
     ●   QtOpenGL        ●   QtXml
     ●   QtOpenVG        ●   QtXmlPatterns
     ●   QtScript        ●   Phonon
    ものすごく多機能で、提供されるコンポーネント量も膨大ですが、モジュール分
    割の粒度と命名規則がスマートなので、使いたい機能を比較的楽に探し出せる
                                Copyright (c) 2011 Ransui Iso, All rights reserved.
C++プログラミングの現実



 C++闇の軍団が
怖いので自粛します

           Copyright (c) 2011 Ransui Iso, All rights reserved.
言語バインディング
●   まぁ色々と大変なのでもっと気軽に使いたい
     –   いわゆるLL系言語を含んだ沢山の言語バインディングが
         あります


         Ada      C#       D   Haskell           Harbor
         Java     CommonLisp   Lua               Ocaml
         Pascal   Perl     PHP Python            R
         Ruby     Scheme       Tcl


         これで全部ではないはずです。


                                         Copyright (c) 2011 Ransui Iso, All rights reserved.
PyQt
●   QtライブラリのPythonバインディング
     –   Riverbank Computingという会社が作っている
     –   最新のQtバージョンへの対応はそれなりに速い
     –   主要なモジュールはほぼ全てサポートしている
     –   SIPというC++とPythonを繋ぐ独自の仕組みで構築


●   ライセンス形態
     –   GPLv2 or GPLv3 (LGPLではないので注意)
     –   Commercial License 有り
          ●   PySideという別のバインディングもあります
          ●   ライセンスはLGPLv2.1で使いやすいかも!

                                 Copyright (c) 2011 Ransui Iso, All rights reserved.
開発環境の整備
Install Python, PyQt and tools into your machine




                                  Copyright (c) 2011 Ransui Iso, All rights reserved.
インストールにあたって
●   Windowsへの導入について説明します
     –   LinuxやMacOSを使っている人は自力で出来るでしょ?
          ●   ほとんどのディストリのパッケージに登録されているはずなの
              でコマンド一発でインストールのはず


●   バージョンについて
     –   Python Version 3.2.x for Windows
          ●   PyQtを使う場合はPython3系が圧倒的に便利

     –   PyQt Version 4.8.5 for Windows
          ●   PyQtをインストールすると自動的にQtも入る


                                      Copyright (c) 2011 Ransui Iso, All rights reserved.
Pythonのインストール
●   MSIパッケージでインストール
     –   http://www.python.org/download
     –   多分これが一番楽
     –   x86とx86-64は別パッケージなので注意
     –   インストール位置とかはデフォルトのままが混乱が少な
         くてよい




                                     Copyright (c) 2011 Ransui Iso, All rights reserved.
環境の確認




        Ctrl-Z + Enter で終了できます
            Copyright (c) 2011 Ransui Iso, All rights reserved.
PyQtのインストール
●   Riverbankからインストーラを入手
     –   http://www.riverbankcomputing.co.uk/software/py
         qt
     –   Python本体をデフォルトでインストールしていれば何
         も変更ぜずにインストールしてしまえば良い。




                                      Copyright (c) 2011 Ransui Iso, All rights reserved.
PyQtの動作確認




PyQt Examples and Demos




                          Copyright (c) 2011 Ransui Iso, All rights reserved.
エディタ・IDE
●   PyScripter : お勧めします
      –   http://code.google.com/p/pyscripter
      –   これもWindowsのインストーラがDLできる
      –   デフォルトのオプションでインストールする
      –   Pythonプログラミングするのに十分な機能を持ったIDE




                                        Copyright (c) 2011 Ransui Iso, All rights reserved.
Off-lineドキュメント
●   別でDLする必要有り
     –   http://qt.nokia.com/downloads
     –   QtSDK Ver 1.1.2のWindows版Online installerをDL
     –   Customインストールを選択
     –   以下のようにドキュメントだけを選択してインストール




           必要なコンポーネントのみが
           DLされインストールされる
                                         Copyright (c) 2011 Ransui Iso, All rights reserved.
Assistantの設定
●   ドキュメントブラウザにデータを設定する
     –

           Assistantを起動する




                      メニューバーから

                      1:【編集(E)】→【設定】でダイアログを開く
                      2:【ドキュメント】タブを選択する
                      3:【追加】ボタンを押す
                      4: C:QtSDKDocumentationの中にある
                          .qchファイルを全部選択して【開く】
                          ボタンを押す




                            Copyright (c) 2011 Ransui Iso, All rights reserved.
やっと環境ができました
●   いよいよPyQtプログラミングの解説です
     –   今まで説明してきたインストール方法で環境が構築され
         ていることが前提です

     –   カスタムインストールした環境ではそのまま動かない例
         があるかもしれませんが、自助努力で頑張ってください

     –   セッション中にデモすることがありますが、環境はKDE
         です。ちょっと見た目とか違いますが、全く同じコード
         がWindows環境でも動作しますので安心してください。



                          Copyright (c) 2011 Ransui Iso, All rights reserved.
HelloWorld
Write and run your first PyQt Application




                              Copyright (c) 2011 Ransui Iso, All rights reserved.
とりあえず始めはこれ
●   PyScripterに以下のソースを書きこむ
    import sys
     import sys
    import PyQt4.QtCore as QtCore
     import PyQt4.QtCore as QtCore
    import PyQt4.QtGui as QtGui
     import PyQt4.QtGui as QtGui

    def main():
     def main():
        app = QtGui.QApplication(sys.argv)
         app = QtGui.QApplication(sys.argv)
        main_window = QtGui.QMainWindow()
         main_window = QtGui.QMainWindow()
        hello_button = QtGui.QPushButton("波浪ワールド")
         hello_button = QtGui.QPushButton("波浪ワールド")
        main_window.setCentralWidget(hello_button)
         main_window.setCentralWidget(hello_button)
        main_window.show()
         main_window.show()
        app.exec_()
         app.exec_()

    if __name__ == '__main__':
     if __name__ == '__main__':
        main()
         main()
                                      ファイル名とかはまだ付けなくても大丈夫



                                           Copyright (c) 2011 Ransui Iso, All rights reserved.
実行してみる
●   PyScripterから実行してみる
     –   スクリプト実行ボタンを押す
     –   メニューの[実行(R)]→[実行(R)]を選択する

                         プログラムに間違いが無ければ、
                         左のように巨大なボタンが1個だ
                         け配置されたウィンドウが表示さ
                         れる。

                         ボタンはクリックできるけれど
                         も、押してもなにも起こらない




                               Copyright (c) 2011 Ransui Iso, All rights reserved.
出てきたQtのコンポーネント
●   QApplication
      –   QtのGUIプログラム全体をコントロールする
      –   コマンドライン引数を要求するので sys.argv を渡す


●   QMainWindow
      –   メインウィンドウを表現する


●   QPushButton
      –   基本的なボタンコンポーネント


                            Copyright (c) 2011 Ransui Iso, All rights reserved.
setCentralWidget()
●   QMainWindowのレイアウトに関係している
     –   MainWindowには、メニューバーやツールバーを配置す
         ることが多いが、QMainWindowは予めこれらをどこに
         配置するかが考慮されている

                      HelloWorldの例では
                      CentralWidgetしか設定していな
                      いので、他の領域は潰されて見え
                      なくなっている




                            Copyright (c) 2011 Ransui Iso, All rights reserved.
exec_() メソッド
●   イベントループを開始するメソッド
                                          ●   GUIシステムはイベントドリブン方
              Application                     式で動いている

                                          ●   Qtは下位のレイヤーが発するイベン
                                              トを拾ってアプリケーションに通知
                   Qt                         する必要がある

                                              Eventの取得                    処理呼び出し
      X11 / Windows

                                                            結果の通知
           OS / Device Driver
                                          ●   この繰り返しをイベントループと呼
                                              ぶ。イベントループが止まるとGUI
Keyboard   Mouse        Monitor   Audio       全体も止まってしまう


                                                 Copyright (c) 2011 Ransui Iso, All rights reserved.
SIGNALとSLOT
Connect control flow between widget and logic




                                Copyright (c) 2011 Ransui Iso, All rights reserved.
イベントに応答するボタン
●   前のソースに追加する
    import sys
     import sys
    import PyQt4.QtCore as QtCore
     import PyQt4.QtCore as QtCore
    import PyQt4.QtGui as QtGui
     import PyQt4.QtGui as QtGui
    def on_click():
     def on_click():
        print("Hello World")
         print("Hello World")
    def main():
     def main():
        app = QtGui.QApplication(sys.argv)
         app = QtGui.QApplication(sys.argv)
        main_window = QtGui.QMainWindow()
         main_window = QtGui.QMainWindow()
        hello_button = QtGui.QPushButton("波浪ワールド")
         hello_button = QtGui.QPushButton("波浪ワールド")
        hello_button.clicked.connect(on_click)
         hello_button.clicked.connect(on_click)
        main_window.setCentralWidget(hello_button)
         main_window.setCentralWidget(hello_button)
        main_window.show()
         main_window.show()
        app.exec_()
         app.exec_()
    if __name__ == '__main__':
     if __name__ == '__main__':
        main()
         main()


                                                      Copyright (c) 2011 Ransui Iso, All rights reserved.
SIGNAL
●   イベント処理のインタフェース
          –    connect()を使って処理ルーチンと接続する


    QMouseEvent         QPushButton
    button                                              on_click()
                                clicked
    position
    globalPosition              pressed

                                released

マウスのボタン操作に関する          内部状態に応じて適切な                 処理ハンドラは普通の
イベントがEvent Loopから      SIGNALがアクティブになる             Python関数で良い
送られてくる



          –    アプリケーションはイベントの詳細を知らずとも
               「何が起こったか」だけを見れば良い
                                           Copyright (c) 2011 Ransui Iso, All rights reserved.
状態を伴ったSIGNAL
●   QCheckBoxで見てみる
    def print_state(state):
     def print_state(state):
        if state == 0:
         if state == 0:
            print("Unchecked")
             print("Unchecked")
        else:
         else:
            print("Checked")
             print("Checked")
    def main():
     def main():
        app = QtGui.QApplication(sys.argv)
         app = QtGui.QApplication(sys.argv)
        main_window = QtGui.QMainWindow()
         main_window = QtGui.QMainWindow()
        check_box = QtGui.QCheckBox("Check box")
         check_box = QtGui.QCheckBox("Check box")
       check_box.stateChanged.connect(print_state)
        check_box.stateChanged.connect(print_state)
        main_window.setCentralWidget(check_box)
         main_window.setCentralWidget(check_box)
        main_window.show()
         main_window.show()
        app.exec_()
         app.exec_()




                                                                  ソースコードは抜粋です

                                                      Copyright (c) 2011 Ransui Iso, All rights reserved.
SIGNAL付随の状態を受け取る
●   引数部分を指定された型で取得できる

         QCheckBox

                stateChanged(int)            print_state(state)

                     clicked(void)

                     pressed(void)

                 released(void)


     –   QCheckBox の stateChanged の場合は、チェックさ
         れている場合は1、されていない場合は0がint型で引数
         としてconnectしているハンドラに渡される

                                     Copyright (c) 2011 Ransui Iso, All rights reserved.
コンポーネント同士を直結する
●   SIGNALとSLOTを接続する
        –   SLOTはSIGNALの受け口関数

    QPushButton            QCheckBox
             clicked               stateChanged                    print_state()

             pressed                   pressed

            released    toggle         released




button.clicked.connect(check_box.toggle)
 button.clicked.connect(check_box.toggle)
check_box.stateChanged.connect(print_state)
 check_box.stateChanged.connect(print_state)
SLOTも普通の関数のようにconnectのターゲットに指定できる。
ただしSIGNALとSLOTを直結する場合は受け渡す値のC++型が一致している必要が
あるので注意する。型の調べ方は後で説明する
                                                  Copyright (c) 2011 Ransui Iso, All rights reserved.
わざわざconnectする理由
●   疎結合にしておくことによるご利益
     –   相互作用のトリガが明示されるので理解しやすい
     –   コンポーネント間の相互作用がロジックに埋もれない
     –   インタフェースが同じなら簡単に差し替え可能
     –   必要なSIGNALのみに処理をconnectすれば良い
     –   1つのSIGNALに複数のハンドラを設定できる
     –   SIGNALとハンドラの接続は実行時に設定&解除可能


●   Qtは徹底して疎結合モデル
     –   大規模なシステムを設計する時の極めて強力な1つの手
         法として大いに参考にできる
                            Copyright (c) 2011 Ransui Iso, All rights reserved.
ラーメンタイマー
A tiny example for design and develop GUI application




                                     Copyright (c) 2011 Ransui Iso, All rights reserved.
ラーメンタイマー伝説
●   2chのスレッド
        –   「Linux使ってこりゃ普及するわけないと思ったとき」
    873:login:Penguin:2009/01/24(土) 23:53:21 ID:AI280zEEdownup
     873:login:Penguin:2009/01/24(土) 23:53:21 ID:AI280zEEdownup
        だいたいLinuxなんてラーメンタイマーさえ作れないだろ。
         だいたいLinuxなんてラーメンタイマーさえ作れないだろ。
        開発環境が整っているとかソフトが豊富で安定してて楽チンとか
         開発環境が整っているとかソフトが豊富で安定してて楽チンとか
        宣伝する割にはさ。
         宣伝する割にはさ。
        それ考えるとWindowsってよく出来てるんじゃない?
         それ考えるとWindowsってよく出来てるんじゃない?
        素人でもラーメンタイマーくらいすぐ作れるし。
         素人でもラーメンタイマーくらいすぐ作れるし。


●   Uncyclopediaの「Linux」の記事
    主な利用者
    主な利用者
      エセSE
      エセSE
      低レベルなサーバー管理者
      低レベルなサーバー管理者
      ただのオタク
      ただのオタク
      ニコニコ動画で3Dデスクトップの動画を見たリア厨
      ニコニコ動画で3Dデスクトップの動画を見たリア厨
      偉そうに語るくせに、ラーメンタイマー1つまともに作ることもできないエセ開発者
      偉そうに語るくせに、ラーメンタイマー1つまともに作ることもできないエセ開発者

                                                       Copyright (c) 2011 Ransui Iso, All rights reserved.
練習題材としてはなかなか良い
●   実装例:RamenTimer.py
      –   3分間カウントダウンするだけの単純なもの




          2chのスレッドではQtは反則ということになっていたようだが
          PyQtセッションなので躊躇なく使うことにする


                              Copyright (c) 2011 Ransui Iso, All rights reserved.
まずは構想&デザイン
●   いきなりコードを書き始めると100%死にます
     –   GUIコンポーネント(Widget)の配置
         ●   スケッチを書いてみる
         ●   機能に注目してUIの領域を分割してみる


     –   プログラムを構成するコンポーネントの階層関係
         ●   UI上の領域と機能の両方を考慮しながらクラスの構成を考える


     –   コンポーネント間の相互作用
         ●   SIGNAL, SLOT, クラスメソッドがどのように連携するかを整理する


     –   「設計」ではなく「デザイン」という観点が大切
         ●   なかなか言葉で表現しにくい
         ●   デザイン中は対象がどんどん変化するので「形式」に拘るのは非効率
                                    Copyright (c) 2011 Ransui Iso, All rights reserved.
コンセプトを決める
●   コンセプトは成果物の基本方針
     –   GUIは「見た目」という強烈な刺激があるので「思いつき」が発生しやす
         く、開発中にあらぬ方向へ進み出す危険性が高い
     –   自分が「なにをしたいのか」「何を作っているのか」を確認するために適
         時振り返るためにもコンセプトは重要
     –   「ココが重要」「これは譲れない」という事項を列挙しただけの簡単なも
         のでも十分に機能する


●   ラーメンタイマーの場合
     –   タイマーなので数字は「見やすく」「でっかく」表示したい
     –   1/100秒単位で表示するとカッコイイかも
     –   カウントダウン中に一時停止やカウンタ値リセットがあると便利
     –   見ただけで操作が分かるようにしたい
     –   とりあえずは3分固定でOK
     –   ... 等々 ...
                                 Copyright (c) 2011 Ransui Iso, All rights reserved.
GUIレイアウト
●   コンセプトに基づいてスケッチしてみる
     –   実際に行うときは「紙と鉛筆」を推奨
         ●   PC上でパワポとか使って検討するのは本当に時間の無駄
         ●   「イケテル!」と確信できた時点で清書すればいい
     –   機能単位に「まとまっている」所を探してみる



                          カウントダウンを実行して表
                          示する部分


                             操作を行う部分

                              Copyright (c) 2011 Ransui Iso, All rights reserved.
コンポーネントの選定と配置
 ●   コンポーネントを積み重ねて構成する
       –   この段階で利用するコンポーネントの当たりをつける
QWidget:QVBoxLayout
QLCDNumberとQTimerを
配置する                        QLCDNumber
                             QLCDNumber




                  QPushButton QPushButton
                   QPushButton QPushButton       QWidget:QGridLayout
                                                 QPushButtonを格子状に
               QPushButton QPushButton           配置する
                QPushButton QPushButton


                            QWidget:QVBoxLayout
                            QMainWindowのCentralWidgetに指定する
                            上に乗る2つのレイヤーを縦方向に整列して配置する
                                             Copyright (c) 2011 Ransui Iso, All rights reserved.
コンポーネントの階層構造
●   コンポーネントの親子関係等を図で整理する
    QMainWindow                   QWidget           attribute           QTimer
    main_window               CountDownWidget                            timer
          CentralWidget         QVBoxLayout
                                                                   QLCDNumber
      QWidget                           instance   addWidget        lcd_number
       panel
                              countdown_widget
    QVBoxLayout
                                                   addWidget        QPushButton
                  addWidget                                         start_button

                                  QWidget                           QPushButton
                              ButtonBoxWidget                       stop_button
                                QGridLayout
                                                                    QPushButton
                                        instance                    reset_button

                              button_box_widget                     QPushButton
                                                                     quit_button

                                                      Copyright (c) 2011 Ransui Iso, All rights reserved.
コンポーネントの相互作用
●   これも図を書いて整理しておくと良い
    start_button                                 timer
                         start_countdown    start
               clicked                                               timeout
                                            stop
    stop_button          stop_countdown
               clicked                            do_countdown

    reset_button           reset_count
                                                          lcd_number
               clicked
                                                    display
                         update_display
    quit_button                                     update

               clicked
                                                          CountDownWidget
                             app
    ButtonBoxWidget        quit
                                           Copyright (c) 2011 Ransui Iso, All rights reserved.
新出コンポーネントのまとめ
●   どれも基本的なものでよく使います
     –   QWidget
          ●   UIを構成する全てのコンポーネントのスーパークラス
          ●   今回はパーツを束ねるコンテナ(トレイ)として使用

     –   QLCDNumber
          ●   液晶風の数値表示ウィジェット

     –   QTimer
          ●   一定時間毎に指定された処理を呼び出す

     –   QGridLayout, QVBoxLayout
          ●   GUIパーツを整列させるためのレイアウトマネージャ
                                    Copyright (c) 2011 Ransui Iso, All rights reserved.
ButtonBoxWidgetの実装
●   まずは方針を確認する
     –   こんな感じに作る予定だったはず


                                    addWidget          QPushButton
                                                       start_button

                      QWidget                          QPushButton
                  ButtonBoxWidget                      stop_button
                    QGridLayout
                                                       QPushButton
                                                       reset_button

                                                       QPushButton
                                                        quit_button




                                    Copyright (c) 2011 Ransui Iso, All rights reserved.
ButtonBoxWidgetのコード
●   素直にコードに落とす
    class ButtonBoxWidget(QtGui.QWidget):
     class ButtonBoxWidget(QtGui.QWidget):
        def __init__(self, parent=None):
         def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent=parent)
             QtGui.QWidget.__init__(self, parent=parent)
            self.setup_ui()
             self.setup_ui()


        def setup_ui(self):
         def setup_ui(self):
            self.start_button = QtGui.QPushButton("STRAT", parent=self)
             self.start_button = QtGui.QPushButton("STRAT", parent=self)
            self.stop_button = QtGui.QPushButton("STOP", parent=self)
             self.stop_button = QtGui.QPushButton("STOP", parent=self)
            self.reset_button = QtGui.QPushButton("RESET", parent=self)
             self.reset_button = QtGui.QPushButton("RESET", parent=self)
            self.quit_button = QtGui.QPushButton("QUIT", parent=self)
             self.quit_button = QtGui.QPushButton("QUIT", parent=self)
            layout = QtGui.QGridLayout()
             layout = QtGui.QGridLayout()
            layout.addWidget(self.start_button, 0, 0)
             layout.addWidget(self.start_button, 0, 0)
            layout.addWidget(self.stop_button, 0, 1)
             layout.addWidget(self.stop_button, 0, 1)
            layout.addWidget(self.reset_button, 1, 0)
             layout.addWidget(self.reset_button, 1, 0)
            layout.addWidget(self.quit_button, 1, 1)
             layout.addWidget(self.quit_button, 1, 1)
            self.setLayout(layout)
             self.setLayout(layout)



                                                         Copyright (c) 2011 Ransui Iso, All rights reserved.
CountDownWidgetの実装
●   方針を確認する
     –   こちらは処理メソッドを実装しないといけない
                      QWidget              attribute              QTimer
                  CountDownWidget                                  timer
                   QVBoxLayout
                                                             QLCDNumber
                                       addWidget              lcd_number

                                                    timer
                     start_countdown            start              timeout
                                                stop
                     stop_countdown
                                                    do_countdown

                       reset_count
                                                            lcd_number
                                                        display
                     update_display
                                                        update
                                       Copyright (c) 2011 Ransui Iso, All rights reserved.
CountDownWidget:UIコード
●    サイズが自動伸長されるようにしてある
    class CountDownWidget(QtGui.QWidget):
     class CountDownWidget(QtGui.QWidget):
        def __init__(self, parent=None):
         def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent=parent)
             QtGui.QWidget.__init__(self, parent=parent)
            self.interval = 10
             self.interval = 10
            self.setup_ui()
             self.setup_ui()
        def setup_ui(self):
         def setup_ui(self):
            self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
             self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
            self.timer = QtCore.QTimer(parent=self)
             self.timer = QtCore.QTimer(parent=self)
            self.timer.setInterval(self.interval)
             self.timer.setInterval(self.interval)
            Self.timer.timeout.connect(self.do_countdown)
             Self.timer.timeout.connect(self.do_countdown)
            self.lcd_number = QtGui.QLCDNumber(parent=self)
             self.lcd_number = QtGui.QLCDNumber(parent=self)
            self.lcd_number.setSizePolicy(QtGui.QSizePolicy.Expanding,
             self.lcd_number.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                          QtGui.QSizePolicy.Expanding)
                                           QtGui.QSizePolicy.Expanding)
            self.lcd_number.setFrameStyle(QtGui.QFrame.NoFrame)
             self.lcd_number.setFrameStyle(QtGui.QFrame.NoFrame)
            self.lcd_number.setSegmentStyle(QtGui.QLCDNumber.Flat)
             self.lcd_number.setSegmentStyle(QtGui.QLCDNumber.Flat)
            self.lcd_number.setDigitCount(6)     
             self.lcd_number.setDigitCount(6)     
            layout = QtGui.QVBoxLayout()
             layout = QtGui.QVBoxLayout()
            layout.addWidget(self.lcd_number)
             layout.addWidget(self.lcd_number)
            self.setLayout(layout)
             self.setLayout(layout)
            self.reset_count()
             self.reset_count()
                                                           Copyright (c) 2011 Ransui Iso, All rights reserved.
CountDownWidget:処理部分
●   以下のようになる
        def update_display(self):
         def update_display(self):
            self.lcd_number.display("%6.2f" % (self.count / 100))
             self.lcd_number.display("%6.2f" % (self.count / 100))
            self.lcd_number.update()
             self.lcd_number.update()
        def do_countdown(self):
         def do_countdown(self):
            self.count ­= 1
             self.count ­= 1
            self.update_display()
             self.update_display()
            if self.count <= 0:
             if self.count <= 0:
                self.stop_countdown()
                 self.stop_countdown()
        def start_countdown(self):
         def start_countdown(self):
            if self.count > 0:
             if self.count > 0:
                self.timer.start()
                 self.timer.start()
        def stop_countdown(self):
         def stop_countdown(self):
            self.timer.stop()
             self.timer.stop()
        def reset_count(self):
         def reset_count(self):
            self.count = 18000
             self.count = 18000
            self.update_display()
             self.update_display()
                                                   Copyright (c) 2011 Ransui Iso, All rights reserved.
MainWindowとかの構成
●   方針の確認

      QMainWindow                           QWidget
      main_window                       CountDownWidget
                                          QVBoxLayout
            CentralWidget
                                                    instance
        QWidget
                            addWidget
         panel                          countdown_widget
      QVBoxLayout

                                            QWidget
                                        ButtonBoxWidget
                                          QGridLayout

                                                    instance

                                        button_box_widget



                                              Copyright (c) 2011 Ransui Iso, All rights reserved.
全体の構成コード
●   main関数として実装してみる
    def main():
     def main():
        app = QtGui.QApplication(sys.argv)
         app = QtGui.QApplication(sys.argv)
        panel = QtGui.QWidget()
         panel = QtGui.QWidget()
        countdown_widget = CountDownWidget(parent=panel)
         countdown_widget = CountDownWidget(parent=panel)
        button_box_widget = ButtonBoxWidget(parent=panel)
         button_box_widget = ButtonBoxWidget(parent=panel)
        panel_layout = QtGui.QVBoxLayout()
         panel_layout = QtGui.QVBoxLayout()
        panel_layout.addWidget(countdown_widget)
         panel_layout.addWidget(countdown_widget)
        panel_layout.addWidget(button_box_widget)
         panel_layout.addWidget(button_box_widget)
        panel.setLayout(panel_layout)
         panel.setLayout(panel_layout)
        panel.setFixedSize(320, 200)
         panel.setFixedSize(320, 200)
        main_window = QtGui.QMainWindow()
         main_window = QtGui.QMainWindow()
        main_window.setWindowTitle("Ramen Timer")
         main_window.setWindowTitle("Ramen Timer")
        main_window.setCentralWidget(panel)
         main_window.setCentralWidget(panel)
        main_window.show()
         main_window.show()


                                                     Copyright (c) 2011 Ransui Iso, All rights reserved.
SIGNALの接続
●   main関数内で行う
    def main():
     def main():
        app = QtGui.QApplication(sys.argv)
         app = QtGui.QApplication(sys.argv)

        ... 中略 ...
         ... 中略 ...
       button_box_widget.start_button.clicked.connect(
        button_box_widget.start_button.clicked.connect(
           countdown_widget.start_countdown)
            countdown_widget.start_countdown)
       button_box_widget.stop_button.clicked.connect(
        button_box_widget.stop_button.clicked.connect(
           countdown_widget.stop_countdown)
            countdown_widget.stop_countdown)
       button_box_widget.reset_button.clicked.connect(
        button_box_widget.reset_button.clicked.connect(
           countdown_widget.reset_count)
            countdown_widget.reset_count)
        button_box_widget.quit_button.clicked.connect(
         button_box_widget.quit_button.clicked.connect(
            app.quit)  
             app.quit)  
        
         
        app.exec_()
         app.exec_()



                                                    Copyright (c) 2011 Ransui Iso, All rights reserved.
ラーメンタイマー完成
●   実際に動かしてみる
●   デザインワークは超大切
●   よりよいラーメンタイマーを目指して
     –   ラーメン出来上がりまで画面注視とかどんだけ
     –   5分のラーメンもあるんですけど
     –   2杯同時に作るときお湯入れるの時間差あるんですが
     –   ワシは「麺硬め」だが奴は「普通」が好みらしい
     –   後入れスープやってる間に麺が伸びちゃうのはNG


         明日のSprintのネタとしてやってみても楽しいかと


                           Copyright (c) 2011 Ransui Iso, All rights reserved.
開発ツール
Introduce some tools for Qt programming




                             Copyright (c) 2011 Ransui Iso, All rights reserved.
assistant
●   Qtのドキュメントビュアー
     –   Webでも参照できるが専用ビュアーは色々と便利
     –   これを使いこなせるようになれば脱初心者
     –   基本英語だけどがんばって!




                         Copyright (c) 2011 Ransui Iso, All rights reserved.
designer
●   GUIレイアウト作成ツール
     –   このツールから入門したくなるという誘引力は強烈




                        Copyright (c) 2011 Ransui Iso, All rights reserved.
designerの暗黒面

        注意・警告
  一見初心者に優しげなこのツールは実は
  上級者向け。QtのGUI構成の基本が分
  かっていない時点で使うと自動生成され
  るコードに振り回される等の「害あって
  も益無し」状態になる可能性が高い

  まずは基本をしっかりマスターしてから
  「手間を減らす」ツールとして使うこと
  を推奨
                Copyright (c) 2011 Ransui Iso, All rights reserved.
Graphics
How to draw graphics on widget




                         Copyright (c) 2011 Ransui Iso, All rights reserved.
Graphicsの取り扱い
●   実装例:アナログ時計




      QtにはOpenGLサポート等の高度なグラフィックス
      処理機能があるが、今回は最も基本的な機能を使って
      作ってみる
                         Copyright (c) 2011 Ransui Iso, All rights reserved.
コンポーネント構成
●    操作する部分が無いのでシンプル
         QMainWindow                            QWidget            attribute              QTimer
         main_window                          ClockWidget                                  timer
                                                     instance
                  CentralWidget
                                                                                       QPixmap
                                              clock_widget                             offscreen




                                                      setup_ui                    timer
                         offscreen
                                                                               start           timeout

                                                     draw_scales
                                        drawing                                              20 times/sec
    QPaintEvent
                                                    draw_needles
                                                                                   redraw_clock
                                  use


                                     paintEvent
                                                                                          ClockWidget
                                                                        Copyright (c) 2011 Ransui Iso, All rights reserved.
Graphics描画機能
●   QPainterというコンポーネントを使う
              painter = QtGui.QPainter()
               painter = QtGui.QPainter()
    描画対象を指定   painter.begin(self.pixmap)
               painter.begin(self.pixmap)



    描画方法の設定   painter.setRenderHint(QtGui.QPainter.Antialiasing)
               painter.setRenderHint(QtGui.QPainter.Antialiasing)


              painter.setPen(QtGui.QPen(QtCore.Qt.white, 4)
               painter.setPen(QtGui.QPen(QtCore.Qt.white, 4)
     描画処理     painter.drawLine(10, 10, 100, 100)
               painter.drawLine(10, 10, 100, 100)
              painter.drawPixmap(30, 10, foo_pixmap)
               painter.drawPixmap(30, 10, foo_pixmap)




     描画終了     painter.end()
               painter.end()



                                            Copyright (c) 2011 Ransui Iso, All rights reserved.
Tiny Media Player
How to playback sound and video data with Qt




                                Copyright (c) 2011 Ransui Iso, All rights reserved.
メディアデータの再生
●   超単純なメディアプレーヤー
     –   Phononというメディア再生フレームワークを使う




                          Copyright (c) 2011 Ransui Iso, All rights reserved.
コンポーネント構成
●   1個のwidgetに全部載せる構成にしている

     QMainWindow                   QWidget                         Phonon.VideoPlayer
     main_window              VideoPlayerWidget                            player
                                 QVBoxLayout
                                        instance       addWidget
              CentralWidget             instance                      QHBoxLayout

                              video_player_widget      QPushButton
                                                    play_pause_button
                                                                                  addWidget
                                                    Phonon.SeekSlider
                                                          slider

        Layoutの上に直接Layoutを追加することができる
          ●    これをうまく使うと相当複雑なレイアウトも実現できる




                                                        Copyright (c) 2011 Ransui Iso, All rights reserved.
Web Browser
Qt has WebKit based browser component




                            Copyright (c) 2011 Ransui Iso, All rights reserved.
QWebKitを使ってみる
●   簡易ブラウザなら簡単に作成可能
                 ●   自作アプリの一部にHTMLVewer
                     として組み込む
                 ●   HTMLパーサとして利用(DOMに
                     アクセスできる)
                 ●   ユーザのアクション(リンクク
                     リック等)を全てHookできるの
                     で挙動のカスタマイズはやり放
                     題
                 ●   本当にHTML+CSS+Javascript
                     レンダリングの機能しかないの
                     で、それなりに使えるブラウザ
                     にするためには結構コードを書
                     かなくちゃいけない




                     Copyright (c) 2011 Ransui Iso, All rights reserved.
GUIはdesignerを使ってみた
●   レイアウトの階層構造を意識しながら作る




      今回はQMainWindowにメニューバーとステータスバー
      も追加している
                        Copyright (c) 2011 Ransui Iso, All rights reserved.
Pythonモジュールの生成
●   pyuic4 コマンドを使う
     –   designerは .ui というXMLファイルを吐き出す
     –   pyuic4 ­­help でオプションを確認できる
     –   基本は以下のように使う
         ●   pyuic4 ­o foo_ui.py foo.ui


     –   出力されるモジュールファイルは手で編集しない
     –   利用の例はソースコードを参照
         ●   この例では TinyBrowser.py がメインで MainWindowUI.py
             が pyuic4 で生成されたGUIコンポーネントのモジュール
         ●   designerを使う場合は、GUIとLogicはモジュール単位で分割され
             ることになる


                                          Copyright (c) 2011 Ransui Iso, All rights reserved.
次のステップへ
Recommended resources and informations about Qt




                                 Copyright (c) 2011 Ransui Iso, All rights reserved.
Qtプログラミングの情報源
●   Qt/PyQtはドキュメントが超充実
     –   ふんだんに用意されているプログラミング例はC++で書
         かれているが、Pythonプログラミングの練習にもなる
         ので、どんどん移植してみよう


●   書籍
     –   日本語で読めるものは少ない!
     –   O'REILLY「入門 Qt4 プログラミング」
         ●   すごく高度な技が載っているわけではない
             が、基本的なGUIコンポーネントをまんべん
             なく取り扱っている。Qtドキュメントとの
             併読がお勧め

                               Copyright (c) 2011 Ransui Iso, All rights reserved.
Thank you for listening
     Happy Hacking with PyQt




                               Copyright (c) 2011 Ransui Iso, All rights reserved.

More Related Content

What's hot

[論文紹介] LSTM (LONG SHORT-TERM MEMORY)
[論文紹介] LSTM (LONG SHORT-TERM MEMORY)[論文紹介] LSTM (LONG SHORT-TERM MEMORY)
[論文紹介] LSTM (LONG SHORT-TERM MEMORY)Tomoyuki Hioki
 
[DL輪読会]SlowFast Networks for Video Recognition
[DL輪読会]SlowFast Networks for Video Recognition[DL輪読会]SlowFast Networks for Video Recognition
[DL輪読会]SlowFast Networks for Video RecognitionDeep Learning JP
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~Takuya Akiba
 
PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門Yosuke Onoue
 
PythonによるCVアルゴリズム実装
PythonによるCVアルゴリズム実装PythonによるCVアルゴリズム実装
PythonによるCVアルゴリズム実装Hirokatsu Kataoka
 
[DL輪読会]YOLO9000: Better, Faster, Stronger
[DL輪読会]YOLO9000: Better, Faster, Stronger[DL輪読会]YOLO9000: Better, Faster, Stronger
[DL輪読会]YOLO9000: Better, Faster, StrongerDeep Learning JP
 
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモAnaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモayohe
 
最適輸送入門
最適輸送入門最適輸送入門
最適輸送入門joisino
 
分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17Takuya Akiba
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision TransformerYusuke Uchida
 
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜Megagon Labs
 
フーリエ変換と画像圧縮の仕組み
フーリエ変換と画像圧縮の仕組みフーリエ変換と画像圧縮の仕組み
フーリエ変換と画像圧縮の仕組みyuichi takeda
 
3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)Toru Tamaki
 
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...joisino
 
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説Takateru Yamagishi
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けモノビット エンジン
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
最適輸送の解き方
最適輸送の解き方最適輸送の解き方
最適輸送の解き方joisino
 
最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)
最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)
最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)Nguyen Tuan
 
Transformer メタサーベイ
Transformer メタサーベイTransformer メタサーベイ
Transformer メタサーベイcvpaper. challenge
 

What's hot (20)

[論文紹介] LSTM (LONG SHORT-TERM MEMORY)
[論文紹介] LSTM (LONG SHORT-TERM MEMORY)[論文紹介] LSTM (LONG SHORT-TERM MEMORY)
[論文紹介] LSTM (LONG SHORT-TERM MEMORY)
 
[DL輪読会]SlowFast Networks for Video Recognition
[DL輪読会]SlowFast Networks for Video Recognition[DL輪読会]SlowFast Networks for Video Recognition
[DL輪読会]SlowFast Networks for Video Recognition
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
 
PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門
 
PythonによるCVアルゴリズム実装
PythonによるCVアルゴリズム実装PythonによるCVアルゴリズム実装
PythonによるCVアルゴリズム実装
 
[DL輪読会]YOLO9000: Better, Faster, Stronger
[DL輪読会]YOLO9000: Better, Faster, Stronger[DL輪読会]YOLO9000: Better, Faster, Stronger
[DL輪読会]YOLO9000: Better, Faster, Stronger
 
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモAnaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
 
最適輸送入門
最適輸送入門最適輸送入門
最適輸送入門
 
分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer
 
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
 
フーリエ変換と画像圧縮の仕組み
フーリエ変換と画像圧縮の仕組みフーリエ変換と画像圧縮の仕組み
フーリエ変換と画像圧縮の仕組み
 
3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)
 
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
 
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
最適輸送の解き方
最適輸送の解き方最適輸送の解き方
最適輸送の解き方
 
最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)
最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)
最近傍探索と直積量子化(Nearest neighbor search and Product Quantization)
 
Transformer メタサーベイ
Transformer メタサーベイTransformer メタサーベイ
Transformer メタサーベイ
 

Viewers also liked

ソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミングソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミングRansui Iso
 
Pythonで電卓アプリ(デスクトップ)を作成する
Pythonで電卓アプリ(デスクトップ)を作成するPythonで電卓アプリ(デスクトップ)を作成する
Pythonで電卓アプリ(デスクトップ)を作成するJun Okazaki
 
QtとC++でGUIプログラミング
QtとC++でGUIプログラミングQtとC++でGUIプログラミング
QtとC++でGUIプログラミングseanchas_t
 
Pythonで画面付きのアプリを作成する
Pythonで画面付きのアプリを作成するPythonで画面付きのアプリを作成する
Pythonで画面付きのアプリを作成するJun Okazaki
 
wxPython入門(大阪Pythonユーザの集まり2014/03)
wxPython入門(大阪Pythonユーザの集まり2014/03)wxPython入門(大阪Pythonユーザの集まり2014/03)
wxPython入門(大阪Pythonユーザの集まり2014/03)泰 増田
 
「Kivyによるアプリケーション開発のすすめ」の勧め
「Kivyによるアプリケーション開発のすすめ」の勧め「Kivyによるアプリケーション開発のすすめ」の勧め
「Kivyによるアプリケーション開発のすすめ」の勧めJun Okazaki
 
Kivyでゲーム
KivyでゲームKivyでゲーム
KivyでゲームJun Okazaki
 
PyconJP2017 Kivyによるアプリケーション開発のすすめ
PyconJP2017 Kivyによるアプリケーション開発のすすめPyconJP2017 Kivyによるアプリケーション開発のすすめ
PyconJP2017 Kivyによるアプリケーション開発のすすめJun Okazaki
 
Clash of Oni Online - VR Multiplay Sword Action
Clash of Oni Online - VR Multiplay Sword Action Clash of Oni Online - VR Multiplay Sword Action
Clash of Oni Online - VR Multiplay Sword Action Yoshifumi Kawai
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...Yoshifumi Kawai
 
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用Yoshifumi Kawai
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Yoshifumi Kawai
 
PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門Hironori Sekine
 
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術Unity Technologies Japan K.K.
 
NextGen Server/Client Architecture - gRPC + Unity + C#
NextGen Server/Client Architecture - gRPC + Unity + C#NextGen Server/Client Architecture - gRPC + Unity + C#
NextGen Server/Client Architecture - gRPC + Unity + C#Yoshifumi Kawai
 
RuntimeUnitTestToolkit for Unity
RuntimeUnitTestToolkit for UnityRuntimeUnitTestToolkit for Unity
RuntimeUnitTestToolkit for UnityYoshifumi Kawai
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門hoxo_m
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践Yoshifumi Kawai
 

Viewers also liked (18)

ソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミングソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミング
 
Pythonで電卓アプリ(デスクトップ)を作成する
Pythonで電卓アプリ(デスクトップ)を作成するPythonで電卓アプリ(デスクトップ)を作成する
Pythonで電卓アプリ(デスクトップ)を作成する
 
QtとC++でGUIプログラミング
QtとC++でGUIプログラミングQtとC++でGUIプログラミング
QtとC++でGUIプログラミング
 
Pythonで画面付きのアプリを作成する
Pythonで画面付きのアプリを作成するPythonで画面付きのアプリを作成する
Pythonで画面付きのアプリを作成する
 
wxPython入門(大阪Pythonユーザの集まり2014/03)
wxPython入門(大阪Pythonユーザの集まり2014/03)wxPython入門(大阪Pythonユーザの集まり2014/03)
wxPython入門(大阪Pythonユーザの集まり2014/03)
 
「Kivyによるアプリケーション開発のすすめ」の勧め
「Kivyによるアプリケーション開発のすすめ」の勧め「Kivyによるアプリケーション開発のすすめ」の勧め
「Kivyによるアプリケーション開発のすすめ」の勧め
 
Kivyでゲーム
KivyでゲームKivyでゲーム
Kivyでゲーム
 
PyconJP2017 Kivyによるアプリケーション開発のすすめ
PyconJP2017 Kivyによるアプリケーション開発のすすめPyconJP2017 Kivyによるアプリケーション開発のすすめ
PyconJP2017 Kivyによるアプリケーション開発のすすめ
 
Clash of Oni Online - VR Multiplay Sword Action
Clash of Oni Online - VR Multiplay Sword Action Clash of Oni Online - VR Multiplay Sword Action
Clash of Oni Online - VR Multiplay Sword Action
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
 
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
 
PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門
 
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術
 
NextGen Server/Client Architecture - gRPC + Unity + C#
NextGen Server/Client Architecture - gRPC + Unity + C#NextGen Server/Client Architecture - gRPC + Unity + C#
NextGen Server/Client Architecture - gRPC + Unity + C#
 
RuntimeUnitTestToolkit for Unity
RuntimeUnitTestToolkit for UnityRuntimeUnitTestToolkit for Unity
RuntimeUnitTestToolkit for Unity
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
 

Similar to PyQtではじめるGUIプログラミング

Cent osにpyhtonをインストールしてみよう
Cent osにpyhtonをインストールしてみようCent osにpyhtonをインストールしてみよう
Cent osにpyhtonをインストールしてみよう2bo 2bo
 
ロボットシステム学2015年第9回
ロボットシステム学2015年第9回ロボットシステム学2015年第9回
ロボットシステム学2015年第9回Ryuichi Ueda
 
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築Hideharu MATSUFUJI
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Masahito Zembutsu
 
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanako
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanakoQtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanako
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanakoKazuo Asano (@kazuo_asa)
 
Eclipse PDT + MakeGood による PHP コードのテスト
Eclipse PDT + MakeGood による PHP コードのテストEclipse PDT + MakeGood による PHP コードのテスト
Eclipse PDT + MakeGood による PHP コードのテストAtsuhiro Kubo
 
2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMF2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMFAtomu Hidaka
 
次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて次世代Webコンテナ Undertowについて
次世代Webコンテナ UndertowについてYoshimasa Tanabe
 
Windowsにpythonをインストールしてみよう
WindowsにpythonをインストールしてみようWindowsにpythonをインストールしてみよう
WindowsにpythonをインストールしてみようKenji NAKAGAKI
 
Next-L Enju 開発ワークショップ #10
Next-L Enju 開発ワークショップ #10Next-L Enju 開発ワークショップ #10
Next-L Enju 開発ワークショップ #10Kosuke Tanabe
 
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 Nagoya
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 NagoyaQtではじめるクロスプラットフォームアプリケーション開発 osc2019 Nagoya
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 NagoyaKazuo Asano (@kazuo_asa)
 
Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)
Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)
Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)Naoki Matsumoto
 
もろもろの AI ツールを Windows のローカル環境にインストールする手順
もろもろの AI ツールを Windows のローカル環境にインストールする手順もろもろの AI ツールを Windows のローカル環境にインストールする手順
もろもろの AI ツールを Windows のローカル環境にインストールする手順Hide Koba
 
サーバ構築自動化 On aws sqaleの場合
サーバ構築自動化 On aws   sqaleの場合サーバ構築自動化 On aws   sqaleの場合
サーバ構築自動化 On aws sqaleの場合Ryo Kuroda
 
今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集Wataru NOGUCHI
 
20130329 rtm2
20130329 rtm220130329 rtm2
20130329 rtm2openrtm
 
Dodai projectの紹介
Dodai projectの紹介Dodai projectの紹介
Dodai projectの紹介Osamu Habuka
 
vscode pipenv docker
vscode pipenv dockervscode pipenv docker
vscode pipenv dockerikdysfm
 

Similar to PyQtではじめるGUIプログラミング (20)

Cent osにpyhtonをインストールしてみよう
Cent osにpyhtonをインストールしてみようCent osにpyhtonをインストールしてみよう
Cent osにpyhtonをインストールしてみよう
 
ロボットシステム学2015年第9回
ロボットシステム学2015年第9回ロボットシステム学2015年第9回
ロボットシステム学2015年第9回
 
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
 
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanako
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanakoQtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanako
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 hamanako
 
Eclipse PDT + MakeGood による PHP コードのテスト
Eclipse PDT + MakeGood による PHP コードのテストEclipse PDT + MakeGood による PHP コードのテスト
Eclipse PDT + MakeGood による PHP コードのテスト
 
2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMF2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMF
 
次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて
 
Windowsにpythonをインストールしてみよう
WindowsにpythonをインストールしてみようWindowsにpythonをインストールしてみよう
Windowsにpythonをインストールしてみよう
 
Golang tokyo #7 qtpm
Golang tokyo #7 qtpmGolang tokyo #7 qtpm
Golang tokyo #7 qtpm
 
Next-L Enju 開発ワークショップ #10
Next-L Enju 開発ワークショップ #10Next-L Enju 開発ワークショップ #10
Next-L Enju 開発ワークショップ #10
 
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 Nagoya
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 NagoyaQtではじめるクロスプラットフォームアプリケーション開発 osc2019 Nagoya
Qtではじめるクロスプラットフォームアプリケーション開発 osc2019 Nagoya
 
Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)
Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)
Qt名古屋勉強会へのお誘い(OSC名古屋2017LT)
 
もろもろの AI ツールを Windows のローカル環境にインストールする手順
もろもろの AI ツールを Windows のローカル環境にインストールする手順もろもろの AI ツールを Windows のローカル環境にインストールする手順
もろもろの AI ツールを Windows のローカル環境にインストールする手順
 
サーバ構築自動化 On aws sqaleの場合
サーバ構築自動化 On aws   sqaleの場合サーバ構築自動化 On aws   sqaleの場合
サーバ構築自動化 On aws sqaleの場合
 
今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集
 
20130329 rtm2
20130329 rtm220130329 rtm2
20130329 rtm2
 
Dodai projectの紹介
Dodai projectの紹介Dodai projectの紹介
Dodai projectの紹介
 
vscode pipenv docker
vscode pipenv dockervscode pipenv docker
vscode pipenv docker
 
Gnomeとdogtai
GnomeとdogtaiGnomeとdogtai
Gnomeとdogtai
 

More from Ransui Iso

「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~Ransui Iso
 
Pythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクターPythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクターRansui Iso
 
アドテクを支える人と技術
アドテクを支える人と技術アドテクを支える人と技術
アドテクを支える人と技術Ransui Iso
 
Playing with curses
Playing with cursesPlaying with curses
Playing with cursesRansui Iso
 
小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話Ransui Iso
 
XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由Ransui Iso
 
Introduction of ToySynth
Introduction of ToySynthIntroduction of ToySynth
Introduction of ToySynthRansui Iso
 
PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.Ransui Iso
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Ransui Iso
 
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Ransui Iso
 
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Ransui Iso
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Ransui Iso
 

More from Ransui Iso (14)

「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~
 
Pythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクターPythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクター
 
アドテクを支える人と技術
アドテクを支える人と技術アドテクを支える人と技術
アドテクを支える人と技術
 
Playing with curses
Playing with cursesPlaying with curses
Playing with curses
 
小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話
 
XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由
 
Introduction of ToySynth
Introduction of ToySynthIntroduction of ToySynth
Introduction of ToySynth
 
PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5
 
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
 

Recently uploaded

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (8)

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 

PyQtではじめるGUIプログラミング

  • 1. PyQtではじめる GUIプログラミング 2011-08-27 Python Conference JP 2011 Ransui Iso Strategic Technology Group / X-Listing Co, Ltd. Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 2. おまえ誰よ? Ransui Iso (磯 蘭水) Work at X-Listing Co, Ltd. http://www.xlisting.co.jp/ Pythonは1998年から使っています。E-Commerceエンジンやサーチエンジンの開 発、Zopeを用いたWebサイト開発、その他色々を経て、今はネット広告配信シス テムについての研究開発をしています。最近はCommon Lispでシステム開発をし ていますが、Pythonもヘビーに使っています。 http://www.facebook.com/ransui @ransui Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 3. 今日お話する内容 ● QtとPyQtについて ● 開発環境を整える ● HelloWorld ● QApplication と Event Loop ● SIGNALとSLOT ● GUIアプリケーション開発の基礎 ● 便利ツール : assistant, designer ● Graphics, Multimedia, Web関連機能 ● さらに先へ行くために Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 4. 対象とするレベル ● Pythonプログラミングの経験 – 午前中のセッション「Pythonチュートリアル」 – 書籍「はじめてのPython」 – Python公式ドキュメント「Pythonチュートリアル」 以上のいずれかをクリアしている方 ● GUIプログラミング経験 – 基本的にGUIプログラミング経験が無い方を想定 – tkinter, wxPython, PyGtk等の経験者の方はPyQt独特の 方法を学ぶ機会になるかと思いますが、多分ドキュメント読 めば独学できる内容 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 5. その他注意点など ● ハンズオンではありません – セッション時間内での演習時間等は予定していません – このスライドは自習時の参考にもなるように作っています ● 当日はご参加ありがとうございました – サンプルコードは以下にあります。 – http://alpa.homeip.net/files/PyConJP2011­SampleCodes.zip ● 質問はfacebook上で – twitterはあまり使っていないので、facebookのメッセージと かでコンタクトしてくれると反応するかもです。 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 6. QtとPyQtについて Introduction of Qt and PyQt Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 7. Qtについて ● クロスプラットフォームのC++総合ライブラリ – 最初期はGUIツールキットとして作られていたが、すぐにC++の総 合ライブラリに成長した – Windows, MacOSX, X11を主要として複数のプラットフォームに 対応している ● ライセンス形態 – LGPL 2.1 + Commercial のデュアルライセンス ● 読み方 – 「きゅーと」と読むらしい – 「きゅーてぃー」でもおおよそ通じると思われる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 8. Qtを使っているもの ● KDE ● Google Earth ● Picasa Client ● VLC Media Player ● Guitar Pro ● Mathmatica ● Skype Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 9. Qtのモジュール群 ● 総合ライブラリと呼ぶに相応しい充実度 ● QtCore ● QtScriptTools ● QtGui ● QtSql ● QtMultimedia ● QtSvg ● QtNetwork ● QtWebKit ● QtOpenGL ● QtXml ● QtOpenVG ● QtXmlPatterns ● QtScript ● Phonon ものすごく多機能で、提供されるコンポーネント量も膨大ですが、モジュール分 割の粒度と命名規則がスマートなので、使いたい機能を比較的楽に探し出せる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 10. C++プログラミングの現実 C++闇の軍団が 怖いので自粛します Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 11. 言語バインディング ● まぁ色々と大変なのでもっと気軽に使いたい – いわゆるLL系言語を含んだ沢山の言語バインディングが あります Ada C# D Haskell Harbor Java CommonLisp Lua Ocaml Pascal Perl PHP Python R Ruby Scheme Tcl これで全部ではないはずです。 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 12. PyQt ● QtライブラリのPythonバインディング – Riverbank Computingという会社が作っている – 最新のQtバージョンへの対応はそれなりに速い – 主要なモジュールはほぼ全てサポートしている – SIPというC++とPythonを繋ぐ独自の仕組みで構築 ● ライセンス形態 – GPLv2 or GPLv3 (LGPLではないので注意) – Commercial License 有り ● PySideという別のバインディングもあります ● ライセンスはLGPLv2.1で使いやすいかも! Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 13. 開発環境の整備 Install Python, PyQt and tools into your machine Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 14. インストールにあたって ● Windowsへの導入について説明します – LinuxやMacOSを使っている人は自力で出来るでしょ? ● ほとんどのディストリのパッケージに登録されているはずなの でコマンド一発でインストールのはず ● バージョンについて – Python Version 3.2.x for Windows ● PyQtを使う場合はPython3系が圧倒的に便利 – PyQt Version 4.8.5 for Windows ● PyQtをインストールすると自動的にQtも入る Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 15. Pythonのインストール ● MSIパッケージでインストール – http://www.python.org/download – 多分これが一番楽 – x86とx86-64は別パッケージなので注意 – インストール位置とかはデフォルトのままが混乱が少な くてよい Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 16. 環境の確認 Ctrl-Z + Enter で終了できます Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 17. PyQtのインストール ● Riverbankからインストーラを入手 – http://www.riverbankcomputing.co.uk/software/py qt – Python本体をデフォルトでインストールしていれば何 も変更ぜずにインストールしてしまえば良い。 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 18. PyQtの動作確認 PyQt Examples and Demos Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 19. エディタ・IDE ● PyScripter : お勧めします – http://code.google.com/p/pyscripter – これもWindowsのインストーラがDLできる – デフォルトのオプションでインストールする – Pythonプログラミングするのに十分な機能を持ったIDE Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 20. Off-lineドキュメント ● 別でDLする必要有り – http://qt.nokia.com/downloads – QtSDK Ver 1.1.2のWindows版Online installerをDL – Customインストールを選択 – 以下のようにドキュメントだけを選択してインストール 必要なコンポーネントのみが DLされインストールされる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 21. Assistantの設定 ● ドキュメントブラウザにデータを設定する – Assistantを起動する メニューバーから 1:【編集(E)】→【設定】でダイアログを開く 2:【ドキュメント】タブを選択する 3:【追加】ボタンを押す 4: C:QtSDKDocumentationの中にある .qchファイルを全部選択して【開く】 ボタンを押す Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 22. やっと環境ができました ● いよいよPyQtプログラミングの解説です – 今まで説明してきたインストール方法で環境が構築され ていることが前提です – カスタムインストールした環境ではそのまま動かない例 があるかもしれませんが、自助努力で頑張ってください – セッション中にデモすることがありますが、環境はKDE です。ちょっと見た目とか違いますが、全く同じコード がWindows環境でも動作しますので安心してください。 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 23. HelloWorld Write and run your first PyQt Application Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 24. とりあえず始めはこれ ● PyScripterに以下のソースを書きこむ import sys import sys import PyQt4.QtCore as QtCore import PyQt4.QtCore as QtCore import PyQt4.QtGui as QtGui import PyQt4.QtGui as QtGui def main(): def main():     app = QtGui.QApplication(sys.argv)     app = QtGui.QApplication(sys.argv)     main_window = QtGui.QMainWindow()     main_window = QtGui.QMainWindow()     hello_button = QtGui.QPushButton("波浪ワールド")     hello_button = QtGui.QPushButton("波浪ワールド")     main_window.setCentralWidget(hello_button)     main_window.setCentralWidget(hello_button)     main_window.show()     main_window.show()     app.exec_()     app.exec_() if __name__ == '__main__': if __name__ == '__main__':     main()     main() ファイル名とかはまだ付けなくても大丈夫 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 25. 実行してみる ● PyScripterから実行してみる – スクリプト実行ボタンを押す – メニューの[実行(R)]→[実行(R)]を選択する プログラムに間違いが無ければ、 左のように巨大なボタンが1個だ け配置されたウィンドウが表示さ れる。 ボタンはクリックできるけれど も、押してもなにも起こらない Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 26. 出てきたQtのコンポーネント ● QApplication – QtのGUIプログラム全体をコントロールする – コマンドライン引数を要求するので sys.argv を渡す ● QMainWindow – メインウィンドウを表現する ● QPushButton – 基本的なボタンコンポーネント Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 27. setCentralWidget() ● QMainWindowのレイアウトに関係している – MainWindowには、メニューバーやツールバーを配置す ることが多いが、QMainWindowは予めこれらをどこに 配置するかが考慮されている HelloWorldの例では CentralWidgetしか設定していな いので、他の領域は潰されて見え なくなっている Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 28. exec_() メソッド ● イベントループを開始するメソッド ● GUIシステムはイベントドリブン方 Application 式で動いている ● Qtは下位のレイヤーが発するイベン トを拾ってアプリケーションに通知 Qt する必要がある Eventの取得 処理呼び出し X11 / Windows 結果の通知 OS / Device Driver ● この繰り返しをイベントループと呼 ぶ。イベントループが止まるとGUI Keyboard Mouse Monitor Audio 全体も止まってしまう Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 29. SIGNALとSLOT Connect control flow between widget and logic Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 30. イベントに応答するボタン ● 前のソースに追加する import sys import sys import PyQt4.QtCore as QtCore import PyQt4.QtCore as QtCore import PyQt4.QtGui as QtGui import PyQt4.QtGui as QtGui def on_click(): def on_click():     print("Hello World")     print("Hello World") def main(): def main():     app = QtGui.QApplication(sys.argv)     app = QtGui.QApplication(sys.argv)     main_window = QtGui.QMainWindow()     main_window = QtGui.QMainWindow()     hello_button = QtGui.QPushButton("波浪ワールド")     hello_button = QtGui.QPushButton("波浪ワールド") hello_button.clicked.connect(on_click) hello_button.clicked.connect(on_click)     main_window.setCentralWidget(hello_button)     main_window.setCentralWidget(hello_button)     main_window.show()     main_window.show()     app.exec_()     app.exec_() if __name__ == '__main__': if __name__ == '__main__':     main()     main() Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 31. SIGNAL ● イベント処理のインタフェース – connect()を使って処理ルーチンと接続する QMouseEvent QPushButton button on_click() clicked position globalPosition pressed released マウスのボタン操作に関する 内部状態に応じて適切な 処理ハンドラは普通の イベントがEvent Loopから SIGNALがアクティブになる Python関数で良い 送られてくる – アプリケーションはイベントの詳細を知らずとも 「何が起こったか」だけを見れば良い Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 32. 状態を伴ったSIGNAL ● QCheckBoxで見てみる def print_state(state): def print_state(state):     if state == 0:     if state == 0:         print("Unchecked")         print("Unchecked")     else:     else:         print("Checked")         print("Checked") def main(): def main():     app = QtGui.QApplication(sys.argv)     app = QtGui.QApplication(sys.argv)     main_window = QtGui.QMainWindow()     main_window = QtGui.QMainWindow()     check_box = QtGui.QCheckBox("Check box")     check_box = QtGui.QCheckBox("Check box") check_box.stateChanged.connect(print_state) check_box.stateChanged.connect(print_state)     main_window.setCentralWidget(check_box)     main_window.setCentralWidget(check_box)     main_window.show()     main_window.show()     app.exec_()     app.exec_() ソースコードは抜粋です Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 33. SIGNAL付随の状態を受け取る ● 引数部分を指定された型で取得できる QCheckBox stateChanged(int) print_state(state) clicked(void) pressed(void) released(void) – QCheckBox の stateChanged の場合は、チェックさ れている場合は1、されていない場合は0がint型で引数 としてconnectしているハンドラに渡される Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 34. コンポーネント同士を直結する ● SIGNALとSLOTを接続する – SLOTはSIGNALの受け口関数 QPushButton QCheckBox clicked stateChanged print_state() pressed pressed released toggle released button.clicked.connect(check_box.toggle) button.clicked.connect(check_box.toggle) check_box.stateChanged.connect(print_state) check_box.stateChanged.connect(print_state) SLOTも普通の関数のようにconnectのターゲットに指定できる。 ただしSIGNALとSLOTを直結する場合は受け渡す値のC++型が一致している必要が あるので注意する。型の調べ方は後で説明する Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 35. わざわざconnectする理由 ● 疎結合にしておくことによるご利益 – 相互作用のトリガが明示されるので理解しやすい – コンポーネント間の相互作用がロジックに埋もれない – インタフェースが同じなら簡単に差し替え可能 – 必要なSIGNALのみに処理をconnectすれば良い – 1つのSIGNALに複数のハンドラを設定できる – SIGNALとハンドラの接続は実行時に設定&解除可能 ● Qtは徹底して疎結合モデル – 大規模なシステムを設計する時の極めて強力な1つの手 法として大いに参考にできる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 36. ラーメンタイマー A tiny example for design and develop GUI application Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 37. ラーメンタイマー伝説 ● 2chのスレッド – 「Linux使ってこりゃ普及するわけないと思ったとき」 873:login:Penguin:2009/01/24(土) 23:53:21 ID:AI280zEEdownup 873:login:Penguin:2009/01/24(土) 23:53:21 ID:AI280zEEdownup だいたいLinuxなんてラーメンタイマーさえ作れないだろ。 だいたいLinuxなんてラーメンタイマーさえ作れないだろ。 開発環境が整っているとかソフトが豊富で安定してて楽チンとか 開発環境が整っているとかソフトが豊富で安定してて楽チンとか 宣伝する割にはさ。 宣伝する割にはさ。 それ考えるとWindowsってよく出来てるんじゃない? それ考えるとWindowsってよく出来てるんじゃない? 素人でもラーメンタイマーくらいすぐ作れるし。 素人でもラーメンタイマーくらいすぐ作れるし。 ● Uncyclopediaの「Linux」の記事 主な利用者 主な利用者 エセSE エセSE 低レベルなサーバー管理者 低レベルなサーバー管理者 ただのオタク ただのオタク ニコニコ動画で3Dデスクトップの動画を見たリア厨 ニコニコ動画で3Dデスクトップの動画を見たリア厨 偉そうに語るくせに、ラーメンタイマー1つまともに作ることもできないエセ開発者 偉そうに語るくせに、ラーメンタイマー1つまともに作ることもできないエセ開発者 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 38. 練習題材としてはなかなか良い ● 実装例:RamenTimer.py – 3分間カウントダウンするだけの単純なもの 2chのスレッドではQtは反則ということになっていたようだが PyQtセッションなので躊躇なく使うことにする Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 39. まずは構想&デザイン ● いきなりコードを書き始めると100%死にます – GUIコンポーネント(Widget)の配置 ● スケッチを書いてみる ● 機能に注目してUIの領域を分割してみる – プログラムを構成するコンポーネントの階層関係 ● UI上の領域と機能の両方を考慮しながらクラスの構成を考える – コンポーネント間の相互作用 ● SIGNAL, SLOT, クラスメソッドがどのように連携するかを整理する – 「設計」ではなく「デザイン」という観点が大切 ● なかなか言葉で表現しにくい ● デザイン中は対象がどんどん変化するので「形式」に拘るのは非効率 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 40. コンセプトを決める ● コンセプトは成果物の基本方針 – GUIは「見た目」という強烈な刺激があるので「思いつき」が発生しやす く、開発中にあらぬ方向へ進み出す危険性が高い – 自分が「なにをしたいのか」「何を作っているのか」を確認するために適 時振り返るためにもコンセプトは重要 – 「ココが重要」「これは譲れない」という事項を列挙しただけの簡単なも のでも十分に機能する ● ラーメンタイマーの場合 – タイマーなので数字は「見やすく」「でっかく」表示したい – 1/100秒単位で表示するとカッコイイかも – カウントダウン中に一時停止やカウンタ値リセットがあると便利 – 見ただけで操作が分かるようにしたい – とりあえずは3分固定でOK – ... 等々 ... Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 41. GUIレイアウト ● コンセプトに基づいてスケッチしてみる – 実際に行うときは「紙と鉛筆」を推奨 ● PC上でパワポとか使って検討するのは本当に時間の無駄 ● 「イケテル!」と確信できた時点で清書すればいい – 機能単位に「まとまっている」所を探してみる カウントダウンを実行して表 示する部分 操作を行う部分 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 42. コンポーネントの選定と配置 ● コンポーネントを積み重ねて構成する – この段階で利用するコンポーネントの当たりをつける QWidget:QVBoxLayout QLCDNumberとQTimerを 配置する QLCDNumber QLCDNumber QPushButton QPushButton QPushButton QPushButton QWidget:QGridLayout QPushButtonを格子状に QPushButton QPushButton 配置する QPushButton QPushButton QWidget:QVBoxLayout QMainWindowのCentralWidgetに指定する 上に乗る2つのレイヤーを縦方向に整列して配置する Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 43. コンポーネントの階層構造 ● コンポーネントの親子関係等を図で整理する QMainWindow QWidget attribute QTimer main_window CountDownWidget timer CentralWidget QVBoxLayout QLCDNumber QWidget instance addWidget lcd_number panel countdown_widget QVBoxLayout addWidget QPushButton addWidget start_button QWidget QPushButton ButtonBoxWidget stop_button QGridLayout QPushButton instance reset_button button_box_widget QPushButton quit_button Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 44. コンポーネントの相互作用 ● これも図を書いて整理しておくと良い start_button timer start_countdown start clicked timeout stop stop_button stop_countdown clicked do_countdown reset_button reset_count lcd_number clicked display update_display quit_button update clicked CountDownWidget app ButtonBoxWidget quit Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 45. 新出コンポーネントのまとめ ● どれも基本的なものでよく使います – QWidget ● UIを構成する全てのコンポーネントのスーパークラス ● 今回はパーツを束ねるコンテナ(トレイ)として使用 – QLCDNumber ● 液晶風の数値表示ウィジェット – QTimer ● 一定時間毎に指定された処理を呼び出す – QGridLayout, QVBoxLayout ● GUIパーツを整列させるためのレイアウトマネージャ Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 46. ButtonBoxWidgetの実装 ● まずは方針を確認する – こんな感じに作る予定だったはず addWidget QPushButton start_button QWidget QPushButton ButtonBoxWidget stop_button QGridLayout QPushButton reset_button QPushButton quit_button Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 47. ButtonBoxWidgetのコード ● 素直にコードに落とす class ButtonBoxWidget(QtGui.QWidget): class ButtonBoxWidget(QtGui.QWidget):     def __init__(self, parent=None):     def __init__(self, parent=None):         QtGui.QWidget.__init__(self, parent=parent)         QtGui.QWidget.__init__(self, parent=parent)         self.setup_ui()         self.setup_ui()     def setup_ui(self):     def setup_ui(self):         self.start_button = QtGui.QPushButton("STRAT", parent=self)         self.start_button = QtGui.QPushButton("STRAT", parent=self)         self.stop_button = QtGui.QPushButton("STOP", parent=self)         self.stop_button = QtGui.QPushButton("STOP", parent=self)         self.reset_button = QtGui.QPushButton("RESET", parent=self)         self.reset_button = QtGui.QPushButton("RESET", parent=self)         self.quit_button = QtGui.QPushButton("QUIT", parent=self)         self.quit_button = QtGui.QPushButton("QUIT", parent=self)         layout = QtGui.QGridLayout()         layout = QtGui.QGridLayout()         layout.addWidget(self.start_button, 0, 0)         layout.addWidget(self.start_button, 0, 0)         layout.addWidget(self.stop_button, 0, 1)         layout.addWidget(self.stop_button, 0, 1)         layout.addWidget(self.reset_button, 1, 0)         layout.addWidget(self.reset_button, 1, 0)         layout.addWidget(self.quit_button, 1, 1)         layout.addWidget(self.quit_button, 1, 1)         self.setLayout(layout)         self.setLayout(layout) Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 48. CountDownWidgetの実装 ● 方針を確認する – こちらは処理メソッドを実装しないといけない QWidget attribute QTimer CountDownWidget timer QVBoxLayout QLCDNumber addWidget lcd_number timer start_countdown start timeout stop stop_countdown do_countdown reset_count lcd_number display update_display update Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 49. CountDownWidget:UIコード ● サイズが自動伸長されるようにしてある class CountDownWidget(QtGui.QWidget): class CountDownWidget(QtGui.QWidget):     def __init__(self, parent=None):     def __init__(self, parent=None):         QtGui.QWidget.__init__(self, parent=parent)         QtGui.QWidget.__init__(self, parent=parent)         self.interval = 10         self.interval = 10         self.setup_ui()         self.setup_ui()     def setup_ui(self):     def setup_ui(self):         self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)         self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)         self.timer = QtCore.QTimer(parent=self)         self.timer = QtCore.QTimer(parent=self)         self.timer.setInterval(self.interval)         self.timer.setInterval(self.interval)         Self.timer.timeout.connect(self.do_countdown)         Self.timer.timeout.connect(self.do_countdown)         self.lcd_number = QtGui.QLCDNumber(parent=self)         self.lcd_number = QtGui.QLCDNumber(parent=self)         self.lcd_number.setSizePolicy(QtGui.QSizePolicy.Expanding,         self.lcd_number.setSizePolicy(QtGui.QSizePolicy.Expanding,                                       QtGui.QSizePolicy.Expanding)                                       QtGui.QSizePolicy.Expanding)         self.lcd_number.setFrameStyle(QtGui.QFrame.NoFrame)         self.lcd_number.setFrameStyle(QtGui.QFrame.NoFrame)         self.lcd_number.setSegmentStyle(QtGui.QLCDNumber.Flat)         self.lcd_number.setSegmentStyle(QtGui.QLCDNumber.Flat)         self.lcd_number.setDigitCount(6)              self.lcd_number.setDigitCount(6)              layout = QtGui.QVBoxLayout()         layout = QtGui.QVBoxLayout()         layout.addWidget(self.lcd_number)         layout.addWidget(self.lcd_number)         self.setLayout(layout)         self.setLayout(layout)         self.reset_count()         self.reset_count() Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 50. CountDownWidget:処理部分 ● 以下のようになる     def update_display(self):     def update_display(self):         self.lcd_number.display("%6.2f" % (self.count / 100))         self.lcd_number.display("%6.2f" % (self.count / 100))         self.lcd_number.update()         self.lcd_number.update()     def do_countdown(self):     def do_countdown(self):         self.count ­= 1         self.count ­= 1         self.update_display()         self.update_display()         if self.count <= 0:         if self.count <= 0:             self.stop_countdown()             self.stop_countdown()     def start_countdown(self):     def start_countdown(self):         if self.count > 0:         if self.count > 0:             self.timer.start()             self.timer.start()     def stop_countdown(self):     def stop_countdown(self):         self.timer.stop()         self.timer.stop()     def reset_count(self):     def reset_count(self):         self.count = 18000         self.count = 18000         self.update_display()         self.update_display() Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 51. MainWindowとかの構成 ● 方針の確認 QMainWindow QWidget main_window CountDownWidget QVBoxLayout CentralWidget instance QWidget addWidget panel countdown_widget QVBoxLayout QWidget ButtonBoxWidget QGridLayout instance button_box_widget Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 52. 全体の構成コード ● main関数として実装してみる def main(): def main():     app = QtGui.QApplication(sys.argv)     app = QtGui.QApplication(sys.argv)     panel = QtGui.QWidget()     panel = QtGui.QWidget()     countdown_widget = CountDownWidget(parent=panel)     countdown_widget = CountDownWidget(parent=panel)     button_box_widget = ButtonBoxWidget(parent=panel)     button_box_widget = ButtonBoxWidget(parent=panel)     panel_layout = QtGui.QVBoxLayout()     panel_layout = QtGui.QVBoxLayout()     panel_layout.addWidget(countdown_widget)     panel_layout.addWidget(countdown_widget)     panel_layout.addWidget(button_box_widget)     panel_layout.addWidget(button_box_widget)     panel.setLayout(panel_layout)     panel.setLayout(panel_layout)     panel.setFixedSize(320, 200)     panel.setFixedSize(320, 200)     main_window = QtGui.QMainWindow()     main_window = QtGui.QMainWindow()     main_window.setWindowTitle("Ramen Timer")     main_window.setWindowTitle("Ramen Timer")     main_window.setCentralWidget(panel)     main_window.setCentralWidget(panel)     main_window.show()     main_window.show() Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 53. SIGNALの接続 ● main関数内で行う def main(): def main():     app = QtGui.QApplication(sys.argv)     app = QtGui.QApplication(sys.argv)     ... 中略 ...     ... 中略 ... button_box_widget.start_button.clicked.connect( button_box_widget.start_button.clicked.connect( countdown_widget.start_countdown) countdown_widget.start_countdown) button_box_widget.stop_button.clicked.connect( button_box_widget.stop_button.clicked.connect( countdown_widget.stop_countdown) countdown_widget.stop_countdown) button_box_widget.reset_button.clicked.connect( button_box_widget.reset_button.clicked.connect( countdown_widget.reset_count) countdown_widget.reset_count) button_box_widget.quit_button.clicked.connect( button_box_widget.quit_button.clicked.connect( app.quit)   app.quit)                 app.exec_()     app.exec_() Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 54. ラーメンタイマー完成 ● 実際に動かしてみる ● デザインワークは超大切 ● よりよいラーメンタイマーを目指して – ラーメン出来上がりまで画面注視とかどんだけ – 5分のラーメンもあるんですけど – 2杯同時に作るときお湯入れるの時間差あるんですが – ワシは「麺硬め」だが奴は「普通」が好みらしい – 後入れスープやってる間に麺が伸びちゃうのはNG 明日のSprintのネタとしてやってみても楽しいかと Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 55. 開発ツール Introduce some tools for Qt programming Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 56. assistant ● Qtのドキュメントビュアー – Webでも参照できるが専用ビュアーは色々と便利 – これを使いこなせるようになれば脱初心者 – 基本英語だけどがんばって! Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 57. designer ● GUIレイアウト作成ツール – このツールから入門したくなるという誘引力は強烈 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 58. designerの暗黒面 注意・警告 一見初心者に優しげなこのツールは実は 上級者向け。QtのGUI構成の基本が分 かっていない時点で使うと自動生成され るコードに振り回される等の「害あって も益無し」状態になる可能性が高い まずは基本をしっかりマスターしてから 「手間を減らす」ツールとして使うこと を推奨 Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 59. Graphics How to draw graphics on widget Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 60. Graphicsの取り扱い ● 実装例:アナログ時計 QtにはOpenGLサポート等の高度なグラフィックス 処理機能があるが、今回は最も基本的な機能を使って 作ってみる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 61. コンポーネント構成 ● 操作する部分が無いのでシンプル QMainWindow QWidget attribute QTimer main_window ClockWidget timer instance CentralWidget QPixmap clock_widget offscreen setup_ui timer offscreen start timeout draw_scales drawing 20 times/sec QPaintEvent draw_needles redraw_clock use paintEvent ClockWidget Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 62. Graphics描画機能 ● QPainterというコンポーネントを使う painter = QtGui.QPainter() painter = QtGui.QPainter() 描画対象を指定 painter.begin(self.pixmap) painter.begin(self.pixmap) 描画方法の設定 painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setPen(QtGui.QPen(QtCore.Qt.white, 4) painter.setPen(QtGui.QPen(QtCore.Qt.white, 4) 描画処理 painter.drawLine(10, 10, 100, 100) painter.drawLine(10, 10, 100, 100) painter.drawPixmap(30, 10, foo_pixmap) painter.drawPixmap(30, 10, foo_pixmap) 描画終了 painter.end() painter.end() Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 63. Tiny Media Player How to playback sound and video data with Qt Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 64. メディアデータの再生 ● 超単純なメディアプレーヤー – Phononというメディア再生フレームワークを使う Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 65. コンポーネント構成 ● 1個のwidgetに全部載せる構成にしている QMainWindow QWidget Phonon.VideoPlayer main_window VideoPlayerWidget player QVBoxLayout instance addWidget CentralWidget instance QHBoxLayout video_player_widget QPushButton play_pause_button addWidget Phonon.SeekSlider slider Layoutの上に直接Layoutを追加することができる ● これをうまく使うと相当複雑なレイアウトも実現できる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 66. Web Browser Qt has WebKit based browser component Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 67. QWebKitを使ってみる ● 簡易ブラウザなら簡単に作成可能 ● 自作アプリの一部にHTMLVewer として組み込む ● HTMLパーサとして利用(DOMに アクセスできる) ● ユーザのアクション(リンクク リック等)を全てHookできるの で挙動のカスタマイズはやり放 題 ● 本当にHTML+CSS+Javascript レンダリングの機能しかないの で、それなりに使えるブラウザ にするためには結構コードを書 かなくちゃいけない Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 68. GUIはdesignerを使ってみた ● レイアウトの階層構造を意識しながら作る 今回はQMainWindowにメニューバーとステータスバー も追加している Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 69. Pythonモジュールの生成 ● pyuic4 コマンドを使う – designerは .ui というXMLファイルを吐き出す – pyuic4 ­­help でオプションを確認できる – 基本は以下のように使う ● pyuic4 ­o foo_ui.py foo.ui – 出力されるモジュールファイルは手で編集しない – 利用の例はソースコードを参照 ● この例では TinyBrowser.py がメインで MainWindowUI.py が pyuic4 で生成されたGUIコンポーネントのモジュール ● designerを使う場合は、GUIとLogicはモジュール単位で分割され ることになる Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 70. 次のステップへ Recommended resources and informations about Qt Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 71. Qtプログラミングの情報源 ● Qt/PyQtはドキュメントが超充実 – ふんだんに用意されているプログラミング例はC++で書 かれているが、Pythonプログラミングの練習にもなる ので、どんどん移植してみよう ● 書籍 – 日本語で読めるものは少ない! – O'REILLY「入門 Qt4 プログラミング」 ● すごく高度な技が載っているわけではない が、基本的なGUIコンポーネントをまんべん なく取り扱っている。Qtドキュメントとの 併読がお勧め Copyright (c) 2011 Ransui Iso, All rights reserved.
  • 72. Thank you for listening Happy Hacking with PyQt Copyright (c) 2011 Ransui Iso, All rights reserved.