PythonとGTKでWebSocketsを使う方法


おいそこ!私はここでWebSocketsでネイティブアプリに素晴らしい旅行を提示するためにここにいる!この場合、これらの技術を使用します.
  • Python
  • GTK +
  • スープ
  • websocketメッセージング
  • あなたがネイティブのGTK +アプリを構築する方法を疑問に思っているなら、私とダイブしましょう!

    理論


    WebSockets クライアントとサーバの間の一貫した接続を提供するように設計されたプロトコルです.それはインターネットまたはチューブの上のワイヤーのようです.そして、クライアントがただデータをサーバーに送ることができて、すぐに反応を得ます.
    このアプローチの利点は非常に明白です:サーバーがクライアントにデータをプッシュするときに別のクライアントからサーバーに来るか、またはバックエンドのどこかに生成されます.クライアントはページを更新したり、新しいデータを取得するために何かを行う必要はありません.
    あなたが見つけることができるWebSocketsに関する詳細情報websocket.org .
    私はそれがWebSocketサーバーに接続し、ネイティブGTK +アプリケーションでそれからデータを送信または受信する方法ですこの記事であなたを表示したい.
    私は私のアプリをコード化されますGNOME Builder , しかし、同じ論理はどこでどこでも働くべきですGTK+ and libsoup 利用可能であり、すべてのコードをMacOSでも簡単に適応することができます.

    UI


    アプリのロジックは非常に簡単なまだ代表です.UIは2つの画面からなるGtk.Grid ) 配置するGtk.Stack . 最初の画面には、サーバーに接続するために必要なウィジェットが含まれますGtk.Entry サーバーのアドレスについては、ボタンと接続を開始するには、スピナーの状態を表示します.

    番目の画面は、より複雑です.この目的は、メッセージを入力し、サーバーに送信し、サーバーの応答を表示することですGtk.TextView . したがって、我々は必要Gtk.Grid ウィジェットを配置する.Gtk.Entry and Gtk.Button 最初のページでも同じようにしました.必要なログを表示するにはGtk.TextView 内に置くGtk.ScrolledWindow ウィンドウが含めることができるより多くのログがある場合、スクロールはできるだけ有用な機能になります.

    接続ページ


    ビルを始めましょう!Builderで新しいプロジェクトを作成します.

    IDEは基本アプリケーションの構造を生成し、必要なのは2つだけです.window.ui and window.py .
    まず、我々のアプリのための正しいUIが必要ですので、オープンwindow.ui . ファイルと置換しますLabel with Gtk.Stack . 2ページ必要です.

    名前の最初の画面“接続”、それに場所Gtk.Grid 3行と列で.中央細胞内Gtk.Box 4行
  • Gtk.Label テキスト"接続"
  • Gtk.Entry . idをhosthostentryに設定する
  • Gtk.Button を指定します.
  • Gtk.Spinner . 好きなことは何でも呼んでください.
  • 「接続」ページには十分です.

    チャットページ


    さらに動く番目の画面は少し複雑です.再び、我々は必要Gtk.Grid 必要なすべてのウィジェットを配置する.しかし、今のところ、それはちょうど2行と2列でグリッドになります.
    つのウィジェットを持つ最初の行.
  • Gtk.Entry を指定します.
  • Gtk.Button ID "sendtice btn "で
  • 二列目にGtk.ScrolledWindow , IDを必要としないので、メソッドを呼び出す必要はありません.このScrolledWindowの中に新しいGtk.TextView ウィジェット.そのIDを"LogRange View "に設定します.
    ScrolledWindow用の属性エディターの中でコンテナの小道具の幅= 2を設定します.

    論理


    OK、out - uiは最終的にいくつかのロジックを構築するのに十分です.
    オープンwindow.py そして、.ui ファイル.
    # Stack with pages
    screens = Gtk.Template.Child()
    
    # Connection page widgets
    host_entry = Gtk.Template.Child()
    connect_btn = Gtk.Template.Child()
    disconnect_btn = Gtk.Template.Child()
    spinner = Gtk.Template.Child()
    
    # Chat page widgets
    send_btn = Gtk.Template.Child()
    message_entry = Gtk.Template.Child()
    log_view = Gtk.Template.Child()
    
    # Declare some class-vars
    self.session = None
    self.connection = None
    
    さて、これらのウィジェットのメソッドを呼び出すことができます.しかし、我々は信号を処理しなければならない.ConnectCore BTNを接続しましょう
    def __init__(self, **kwargs):
        # Some app logic
    
        self.connect_btn.connect('clicked', self.on_connect_clicked)
    
    def on_connect_clicked(self, widget):
        # Check if there is a text inside the host_entry
        # and grab focus if its empty
        if not self.host_entry.get_text():
            self.host_entry.grab_focus()
            return
    
        # Show user we are trying to connect
        self.spinner.start()
    
        # Init libsoup Session, create message and start connection
        self.session = Soup.Session()
        msg = Soup.Message.new("GET", self.host_entry.get_text())
        self.session.websocket_connect_async(msg, None, None, None, self.on_connection)
    
    上のコードはとても簡単です.
  • サーバアドレスを取得する
  • クリエイト Session
  • init接続 websocket_connect_async
  • 接続関数のコールバックとしてon_connection この操作の結果を取り、プロセスを終了するメソッドです.
    def on_connection(self, session, result):
        try:
            # Finish connection process
            self.connection = session.websocket_connect_finish(result)
    
            # If we here, the connection went correctly
            # Connect `message` handler to the connection
            self.connection.connect('message', self.on_message)
    
            # Show to user all is OK and switch to the Chat page
            self.screens.set_visible_child_name('chat')
            self.disconnect_btn.set_visible(True)
    
        except Exception as e:
            # In case something goes wrong just print an exception
            print(e)
            self.session = None
    
        finally:
            # Don't forget to show a user that process is finished.
            self.spinner.stop()
    
    我々はほとんど完了です!より多くのことをする必要があるのは、「sendrest btn」からClickイベントを処理し、「LogRange View」でメッセージを表示することです.
    def on_message(self, connection, msg_type, message):
        msg = f'<b>RECEIVED:</b> {message.get_data().decode()}\n'
        self.buffer.insert_markup(self.buffer.get_start_iter(),
                                  msg,
                                  len(msg))
    
    
    それよりももっと簡単だろうか.😉 ちょうど私たちはいくつかのPangoマークアップと使用を追加読みやすい方法でメッセージを表示するには insert_markup メソッドGtk.TextBuffer …に…マークアップを挿入!
    最後になりますが、少なくとも必要なものは"sendrest btn "シグナルのハンドラです.
    def on_send_clicked(self, widget):
        # Get the message from the Entry
        msg = self.message_entry.get_text()
    
        # If there is no message - grab focus.
        if not msg:
            self.message_entry.grab_focus()
            return
    
        # Send a text to the server.
        self.connection.send_text(msg)
    
    我々の単純なケースのために、我々が必要とするすべては、ちょうどです send_text メソッド.しかし、LibSlopは、などの多くの異なるものを行うことができます send_binary または何かで信号を発するgoes wrong .

    結論


    内部のWebSocketsを使用してGTK +アプリを構築を開始する方法のシンプルでわかりやすい例.たぶんあなたは新しいチャットアプリケーションを作成しますか?
    あなたがより多くを読みたいならば、調整されてください!またはリンクのセクションからドキュメントに移動します.
    とにかく、幸運!

    リンク


    ソースコード:
    https://github.com/amka/pygobject-gtk-websocket-app
    ドキュメント
  • https://websocket.org/
  • https://lazka.github.io/pgi-docs/#Gtk-3.0
  • https://lazka.github.io/pgi-docs/#Soup-2.4