TenderOwl
Hey there! I’m here to present you an amazing trip to the native apps with WebSockets!
In this current case we will be using these technologies:
If you’re wondering how to build a native GTK+ chat app, let’s dive with me!
WebSockets is a protocol designed to provide a consistent connection between the client and a server where both can send data to each other. It’s like a wire over the Internet or a tube, distinct of regular HTTP, where the client only can send data to the server and it gets a response immediately.
Benefits of this approach are quite obvious: the server can push the data to the client when it comes to server from another client or generated somewhere on the backend. And the client doesn’t need to refresh the page or do something to fetch new data, it just comes to the client by itself.
More information about WebSockets you can find on the websocket.org.
What I want to show you in this article it is how to connect to a WebSocket server and send or receive data from it in a native GTK+ application.
I will code my app in elementary OS using GNOME Builder, but the same logic should work anywhere where GTK+ and libsoup are available and all code could be easily adapted even for macOS.
The app logic is quite simple yet representative. The UI will consist of two screens (Gtk.Grid
) placed in Gtk.Stack
. The first screen contains widgets required to connect to the server such as Gtk.Entry
for server address, button to initiate a connection and a spinner to show the state.
The second screen is more complex. Purpose of this is to enter the message, send it to the server and show the server’s response in Gtk.TextView
. Thus we need Gtk.Grid
to place widgets. Gtk.Entry
and Gtk.Button
the same way we did it on the first page. And to display log we need Gtk.TextView
placed within Gtk.ScrolledWindow
in case there will be much more logs than the window can contain and the scrolling will be as much useful feature as it could :)
Let’s start building! Create a new project in Builder, as the language, we will use Python 3.6+.
IDE will generate a base app structure with all we need, and all we need is just two files: window.ui
and window.py
.
Firstly, we need a correct UI for our app, so open window.ui
. file and replace the “hello world” Label
with Gtk.Stack
. We will need two pages.
Name the first screen “connection”, and place onto it Gtk.Grid
with 3 rows and columns. In the central cell place Gtk.Box
with 4 rows:
Gtk.Label
with text “Connection”Gtk.Entry
. Set its id to “host_entry”Gtk.Button
with id “connect_btn”Gtk.Spinner
. Call it whatever you like, mine is just a “spinner” :)That’s enough for the “Connection” page.
Moving further. The second screen is a bit more complex. Again, we need Gtk.Grid
to put all the widgets we need. But for now, it will be a grid with just 2 rows and 2 columns.
First row with two widgets in its own cells:
Gtk.Entry
with id “message_entry”Gtk.Button
with id “send_btn”On the second row place Gtk.ScrolledWindow
, no id required because we don’t need to call its method. Inside this ScrolledWindow put a new Gtk.TextView
widget. Set its id to “log_view”.
To make it looks more convenient, set width = 2 in the container’s props inside attribute editor for ScrolledWindow.
Ok, out UI is ready enough to build some logic for it, finally :)
Open window.py
and add class vars to connect with widgets from the .ui
file.
|
|
Well, now we are able to call methods of these widgets. But also, we have to handle its signals. Let’s connect “connect_btn”:
|
|
The code above is quite straightforward:
Session
websocket_connect_async
As a callback for connection function, we put on_connection
method, which takes the result of this operation and finish the process.
|
|
We are almost done! All we need to do more is to handle click event from the “send_btn” and display messages in the “log_view”.
|
|
Could it be more simple than that? :wink: Just to display a message in a more readable way we add some Pango markup and use insert_markup
method of Gtk.TextBuffer
to… insert markup!
Last, but not least required thing is a handler for “send_btn” signal.
|
|
For our simple case, all we need is just the send_text
method. But libsoup could do a lot of different stuff, such as send_binary
or emit a signal if something goes wrong.
Simple yet descriptive example of how to start building your GTK+ app with WebSockets inside. Maybe you will create a new chat app?
Stay tuned if you want to read more! Or go to the docs from the Links section.
Anyway, good luck!
Source code: https://github.com/amka/pygobject-gtk-websocket-app
Docs: