Awesome  Rust

Awesome Rust


Iced RS: A Cross-platform GUI Library for Rust


A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm.


Iced is currently experimental software. Take a look at the roadmap, check out the issues, and feel free to contribute!


Add iced as a dependency in your Cargo.toml:

iced = "0.4"

If your project is using a Rust edition older than 2021, then you will need to set resolver = "2" in the [package] section as well.

Iced moves fast and the master branch can contain breaking changes! If you want to learn about a specific release, check out the release list.


Inspired by The Elm Architecture, Iced expects you to split user interfaces into four different concepts:

  • State — the state of your application
  • Messages — user interactions or meaningful events that you care about
  • View logic — a way to display your state as widgets that may produce messages on user interaction
  • Update logic — a way to react to messages and update your state

We can build something to see how this works! Let's say we want a simple counter that can be incremented and decremented using two buttons.

We start by modelling the state of our application:

use iced::button;

struct Counter {
    // The counter value
    value: i32,

    // The local state of the two buttons
    increment_button: button::State,
    decrement_button: button::State,

Next, we need to define the possible user interactions of our counter: the button presses. These interactions are our messages:

#[derive(Debug, Clone, Copy)]
pub enum Message {

Now, let's show the actual counter by putting it all together in our view logic:

use iced::{Button, Column, Text};

impl Counter {
    pub fn view(&mut self) -> Column<Message> {
        // We use a column: a simple vertical layout
                // The increment button. We tell it to produce an
                // `IncrementPressed` message when pressed
                Button::new(&mut self.increment_button, Text::new("+"))
                // We show the value of the counter here
                // The decrement button. We tell it to produce a
                // `DecrementPressed` message when pressed
                Button::new(&mut self.decrement_button, Text::new("-"))

Finally, we need to be able to react to any produced messages and change our state accordingly in our update logic:

impl Counter {
    // ...

    pub fn update(&mut self, message: Message) {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            Message::DecrementPressed => {
                self.value -= 1;

And that's everything! We just wrote a whole user interface. Iced is now able to:

  1. Take the result of our view logic and layout its widgets.
  2. Process events from our system and produce messages for our update logic.
  3. Draw the resulting user interface.

Browse the documentation and the examples to learn more!

Implementation details

Iced was originally born as an attempt at bringing the simplicity of Elm and The Elm Architecture into Coffee, a 2D game engine I am working on.

The core of the library was implemented during May 2019 in this pull request. The first alpha version was eventually released as a renderer-agnostic GUI library. The library did not provide a renderer and implemented the current tour example on top of ggez, a game library.

Since then, the focus has shifted towards providing a batteries-included, end-user-oriented GUI library, while keeping the ecosystem modular:

The Iced Ecosystem 



This occurs when the selected built-in renderer is not able to create a context.

Often this will occur while using iced_wgpu as the renderer without supported hardware (needs Vulkan, Metal or DX12). In this case, you could try using the iced_glow renderer:

First, check if it works with

cargo run --features iced/glow --package game_of_life

and then use it in your project with

iced = { version = "0.4", default-features = false, features = ["glow"] }

NOTE: Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0, but if you don't, right now there's no software fallback, so it means your hardware doesn't support Iced.

Contributing / Feedback

Contributions are greatly appreciated! If you want to contribute, please read our contributing guidelines for more details.

Feedback is also welcome! You can open an issue or, if you want to talk, come chat to our Discord server. Moreover, you can find me (and a bunch of awesome folks) over the #games-and-graphics and #gui-and-ui channels in the Rust Community Discord. I go by lone_scientist#9554 there.


68747470733a2f2f7468756d62732e6766796361742e636f6d2f4c6974746c6553616e6548616c69636f72652d736d616c6c2e676966 68747470733a2f2f7468756d62732e6766796361742e636f6d2f506f6c69746541646f7261626c654962657269616e6d6f6c652d736d616c6c2e676966

Download Details:
Author: iced-rs
Source Code:
License: MIT license

#rust #applications

Iced RS: A Cross-platform GUI Library for Rust

PyAutoGUI: A Cross-Platform GUI Automation Python Module


PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

pip install pyautogui

Full documentation available at

Simplified Chinese documentation available at

Source code available at

If you need help installing Python, visit


PyAutoGUI supports Python 2 and 3. If you are installing PyAutoGUI from PyPI using pip:

Windows has no dependencies. The Win32 extensions do not need to be installed.

macOS needs the pyobjc-core and pyobjc module installed (in that order).

Linux needs the python3-xlib (or python-xlib for Python 2) module installed.

Pillow needs to be installed, and on Linux you may need to install additional libraries to make sure Pillow's PNG/JPEG works correctly. See:

If you want to do development and contribute to PyAutoGUI, you will need to install these modules from PyPI:

  • pyscreeze
  • pymsgbox
  • pytweening

Example Usage

Keyboard and Mouse Control

The x, y coordinates used by PyAutoGUI has the 0, 0 origin coordinates in the top left corner of the screen. The x coordinates increase going to the right (just as in mathematics) but the y coordinates increase going down (the opposite of mathematics). On a screen that is 1920 x 1080 pixels in size, coordinates 0, 0 are for the top left while 1919, 1079 is for the bottom right.

Currently, PyAutoGUI only works on the primary monitor. PyAutoGUI isn't reliable for the screen of a second monitor (the mouse functions may or may not work on multi-monitor setups depending on your operating system and version).

All keyboard presses done by PyAutoGUI are sent to the window that currently has focus, as if you had pressed the physical keyboard key.

    >>> import pyautogui
    >>> screenWidth, screenHeight = pyautogui.size() # Returns two integers, the width and height of the screen. (The primary monitor, in multi-monitor setups.)
    >>> currentMouseX, currentMouseY = pyautogui.position() # Returns two integers, the x and y of the mouse cursor's current position.
    >>> pyautogui.moveTo(100, 150) # Move the mouse to the x, y coordinates 100, 150.
    >>> # Click the mouse at its current location.
    >>>, 220) # Click the mouse at the x, y coordinates 200, 220.
    >>> pyautogui.move(None, 10)  # Move mouse 10 pixels down, that is, move the mouse relative to its current position.
    >>> pyautogui.doubleClick() # Double click the mouse at the
    >>> pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeInOutQuad) # Use tweening/easing function to move mouse over 2 seconds.
    >>> pyautogui.write('Hello world!', interval=0.25)  # Type with quarter-second pause in between each key.
    >>>'esc') # Simulate pressing the Escape key.
    >>> pyautogui.keyDown('shift')
    >>> pyautogui.write(['left', 'left', 'left', 'left', 'left', 'left'])
    >>> pyautogui.keyUp('shift')
    >>> pyautogui.hotkey('ctrl', 'c')

Display Message Boxes

    >>> import pyautogui
    >>> pyautogui.alert('This is an alert box.')
    >>> pyautogui.confirm('Shall I proceed?')
    >>> pyautogui.confirm('Enter option.', buttons=['A', 'B', 'C'])
    >>> pyautogui.prompt('What is your name?')
    >>> pyautogui.password('Enter password (text will be hidden)')

Screenshot Functions

(PyAutoGUI uses Pillow for image-related features.)

    >>> import pyautogui
    >>> im1 = pyautogui.screenshot()
    >>> im2 = pyautogui.screenshot('my_screenshot2.png')

You can also locate where an image is on the screen:

    >>> import pyautogui
    >>> button7location = pyautogui.locateOnScreen('button.png') # returns (left, top, width, height) of matching region
    >>> button7location
    (1416, 562, 50, 41)
    >>> buttonx, buttony =
    >>> buttonx, buttony
    (1441, 582)
    >>>, buttony)  # clicks the center of where the button was found

The locateCenterOnScreen() function returns the center of this match region:

    >>> import pyautogui
    >>> buttonx, buttony = pyautogui.locateCenterOnScreen('button.png') # returns (x, y) of matching region
    >>> buttonx, buttony
    (1441, 582)
    >>>, buttony)  # clicks the center of where the button was found

How Does PyAutoGUI Work?

The three major operating systems (Windows, macOS, and Linux) each have different ways to programmatically control the mouse and keyboard. This can often involve confusing, obscure, and deeply technical details. The job of PyAutoGUI is to hide all of this complexity behind a simple API.

On Windows, PyAutoGUI accesses the Windows API (also called the WinAPI or win32 API) through the built-in ctypes module. The nicewin module at provides a demonstration for how Windows API calls can be made through Python.

On macOS, PyAutoGUI uses the rubicon-objc module to access the Cocoa API.

On Linux, PyAutoGUI uses the Xlib module to access the X11 or X Window System.


If you find this project helpful and would like to support its development, consider donating to its creator on Patreon.

Author: asweigart
Source Code:
License: BSD-3-Clause License

#python #gui 

PyAutoGUI: A Cross-Platform GUI Automation Python Module
渚  直樹

渚 直樹





00:00 イントロ
02:05 PyAutoGUI使用のための準備
04:50 基本的な操作
14:50 Excelのフィルター設定をONにする
32:00 Excelファイルのフィルター設定の自動化

#python #gui   


Awesome Python: Libraries for Working with GUI Applications

GUI Development

Libraries for working with graphical user interface applications.

  • curses - Built-in wrapper for ncurses used to create terminal GUI applications.
  • Eel - A library for making simple Electron-like offline HTML/JS GUI apps.
  • enaml - Creating beautiful user-interfaces with Declarative Syntax like QML.
  • Flexx - Flexx is a pure Python toolkit for creating GUI's, that uses web technology for its rendering.
  • Gooey - Turn command line programs into a full GUI application with one line.
  • kivy - A library for creating NUI applications, running on Windows, Linux, Mac OS X, Android and iOS.
  • pyglet - A cross-platform windowing and multimedia library for Python.
  • PyGObject - Python Bindings for GLib/GObject/GIO/GTK+ (GTK+3).
  • PyQt - Python bindings for the Qt cross-platform application and UI framework.
  • PySimpleGUI - Wrapper for tkinter, Qt, WxPython and Remi.
  • pywebview - A lightweight cross-platform native wrapper around a webview component.
  • Tkinter - Tkinter is Python's de-facto standard GUI package.
  • Toga - A Python native, OS native GUI toolkit.
  • urwid - A library for creating terminal GUI applications with strong support for widgets, events, rich colors, etc.
  • wxPython - A blending of the wxWidgets C++ class library with the Python.
  • DearPyGui - A Simple GPU accelerated Python GUI framework

Author: vinta
Source Code:
License: View license

#python #gui 

Awesome Python: Libraries for Working with GUI Applications

Toga: A Python Native, OS Native GUI Toolkit


A Python native, OS native GUI toolkit.


Minimum requirements

  • Toga requires Python 3.7 or higher. Python 2 is not supported.
  • If you're on macOS, you need to be on 10.10 (Yosemite) or newer.
  • If you're on Linux, you need to have GTK+ 3.10 or newer. This is the version that ships starting with Ubuntu 14.04 and Fedora 20. You also need to install the Python 3 bindings and development files for GTK+.
    • Ubuntu 16.04 / Debian 9 sudo apt-get install python3-dev python3-gi python3-gi-cairo libgirepository1.0-dev libcairo2-dev libpango1.0-dev libwebkitgtk-3.0-0 gir1.2-webkit2-3.0
    • Ubuntu 18.04, 20.04 / Debian 10, 11 sudo apt-get install python3-dev python3-gi python3-gi-cairo libgirepository1.0-dev libcairo2-dev libpango1.0-dev libwebkit2gtk-4.0-37 gir1.2-webkit2-4.0
    • Fedora sudo dnf install pygobject3 python3-gobject python3-cairo-devel cairo-gobject-devel gobject-introspection-devel pywebkitgtk
    • Arch / Manjaro sudo pacman -Syu git pkgconf cairo python-cairo pango gobject-introspection gobject-introspection-runtime python-gobject webkit2gtk
  • If you're on Windows, you'll need Windows 10 or newer.


To get a demonstration of the capabilities of Toga, run the following:

$ pip install --pre toga-demo
$ toga-demo

This will pop up a GUI window with some sample widgets.


Documentation for Toga can be found on Read The Docs.


Toga is part of the BeeWare suite. You can talk to the community through:


If you'd like to contribute to Toga development, our guide for first time contributors will help you get started.

If you experience problems with Toga, log them on GitHub. If you want to contribute code, please fork the code and submit a pull request.

Author: beeware
Source Code:
License: View license

#python #gui 

Toga: A Python Native, OS Native GUI Toolkit

Pywebview: Build GUI for Python Program with JavaScript, HTML and CSS

pywebview is a lightweight cross-platform wrapper around a webview component that allows to display HTML content in its own native GUI window. It gives you power of web technologies in your desktop application, hiding the fact that GUI is browser based. You can use pywebview either with a lightweight web framework like Flask or Bottle or on its own with a two way bridge between Python and DOM.

pywebview uses native GUI for creating a web component window: WinForms on Windows, Cocoa on macOS and QT or GTK on Linux. If you choose to freeze your application, pywebview does not bundle a heavy GUI toolkit or web renderer with it keeping the executable size small. pywebview is compatible with Python 3.

pywebview is created by Roman Sirokov.

Getting started


pip install pywebview
  • Currently only python version 3.8 or older supported on Windows.
  • On Linux you need additional libraries. Refer to the installation page for details.

Hello world

import webview
webview.create_window('Hello world', '')

Explore pywebview further by reading documentation, examples or contributing. If React is your thing, get started right away with React boilerplate.


Code Contributors

This project exists thanks to all the people who contribute. [Contribute]. 

Financial Contributors

Become a financial contributor and help us sustain our community. More donation options are outlined on the Donating page.



Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

Author: r0x0r
Source Code:
License: BSD-3-Clause License

#python #gui #css #html #javascript 

Pywebview: Build GUI for Python Program with JavaScript, HTML and CSS

PySimpleGUI: Python GUIs for Humans

Python GUIs for Humans

Transforms the tkinter, Qt, WxPython, and Remi (browser-based) GUI frameworks into a simpler interface. The window definition is simplified by using Python core data types understood by beginners (lists and dictionaries). Further simplification happens by changing event handling from a callback-based model to a message passing one.

Your code is not required to have an object oriented architecture which makes the package usable by a larger audience. While the architecture is simple to understand, it does not necessarily limit you to only simple problems.

Some programs are not well-suited for PySimpleGUI however. By definition, PySimpleGUI implements a subset of the underlying GUI frameworks' capabilities. It's difficult to define exactly which programs are well suited for PySimpleGUI and which are not. It depends on the details of your program. Duplicating Excel in every detail is an example of something not well suited for PySimpleGUI.

Japanese version of this readme.

PySimpleGUI needs your support. If you find PySimpleGUI useful, please consider sponsoring the project on GitHub or BuyMeACoffee. It's expensive working full-time on PySimpleGUI and also paying for ongoing expenses (domains, artists, software, consultants, sponsoring open source projects).

What Is PySimpleGUI ❓

PySimpleGUI is a Python package that enables Python programmers of all levels to create GUIs. You specify your GUI window using a "layout" which contains widgets (they're called "Elements" in PySimpleGUI). Your layout is used to create a window using one of the 4 supported frameworks to display and interact with your window. Supported frameworks include tkinter, Qt, WxPython, or Remi. The term "wrapper" is sometimes used for these kinds of packages.

Your PySimpleGUI code is simpler and shorter than writing directly using the underlying framework because PySimpleGUI implements much of the "boilerplate code" for you. Additionally, interfaces are simplified to require as little code as possible to get the desired result. Depending on the program and framework used, a PySimpleGUI program may require 1/2 to 1/10th amount of code to create an identical window using one of the frameworks directly.

While the goal is to encapsulate/hide the specific objects and code used by the GUI framework you are running on top of, if needed you can access the frameworks' dependent widgets and windows directly. If a setting or feature is not yet exposed or accessible using the PySimpleGUI APIs, you are not walled off from the framework. You can expand capabilities without directly modifying the PySimpleGUI package itself.

Bridging the "GUI Gap"

Python has brought a large number of people into the programming community. The number of programs and the range of areas it touches is mindboggling. But more often than not, these technologies are out of reach of all but a handful of people. The majority of Python programs are "command line" based. This isn't a problem for programmer-types as we're all used to interacting with computers through a text interface. While programmers don't have a problem with command-line interfaces, most "normal people" do. This creates a digital divide, a "GUI Gap".

Adding a GUI to a program opens that program up to a wider audience. It becomes more approachable. GUIs can also make interacting with some programs easier, even for those that are comfortable with a command-line interface. And finally, some problems require a GUI.

Recognition of Open Source Use

In the Demo Programs or one of the PySimpleGUI Account's Repos these packages were used at least one time. Some of your are the goodies on the right of the GUI gap.

If you use Open Source software in your project, be sure and supply information about the packages you used.

  • chatterbot
  • cv2
  • fitz
  • forecastio
  • gtts
  • matplotlib
  • mido
  • mpl_toolkits
  • notifypy
  • numpy
  • pandas
  • PIL
  • praw
  • psgtray
  • psutil
  • pyfiglet
  • pygame
  • pylab
  • pymunk
  • requests
  • vlc
  • win32api
  • win32con
  • win32gui
  • win32process

LPLG3 as an Example

The licensing terms in the LLC3 Licensing, it states:

  1. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:

a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.

b) Accompany the Combined Work with a copy of the GNU GPL and this license document.

Since the above packages each have a similar license clause, I'm listing them here, in what I would consider a "prominent notice" location, that I'm using the fine works of these groups or individuals. They are used in the Demo Programs most likely or one of the Repos that are under this account as this list is all inclusive.

You all have my respect and admiration. You're enabling bigger things. What a special kind of thing to make. Who knows what you've enabled. I believe more people are getting over to your creations and getting to experience them.

tkinter team - PySimpleGUI would be nowhere without your lengthy work & continuous dedication. ONE GUI API for 3 different OS's? Really? With no code changes to move between? That's a huge accomplishment. You're #1 to me. Thank you for your hard work 🙏.

Getting Over "The Bar"

It's been said by some that "the bar is pretty high" when it comes to learning GUI programming in Python.

What happens when the bar is placed on the ground and can be stepped over?

This is one of the questions that the PySimpleGUI project has tried to answer. Here's a humorous look at what's been a not funny situation.

The results have been fascinating to witness and it's been touching to read the accounts of the journeys of users.

Nothing prepared me for the emails that started to arrive soon after the first release of PySimpleGUI. They are heartwarming and heartbreaking tales of life-long dreams of creating a program that required a GUI. Some made a few attempts, giving up each time. Others never started once they started to research what was required.

After recounting the varied and long road to finding PySimpleGUI, the stories became similar. They each found success and expressed joy and gratitude. The joy expressed in these messages was unlike anything I had encountered in the entirety of career in the computing field.

It's been these emails and the messages of gratitude seen here in the GitHub Issues that made dedicating my life to his project a non-decision.

Subscribing to Announcements 📢

If you click the "Subscribe" button in the Announcements GitHub Issue, then you'll be notified when project news is published. This Issue is the official location to get the latest PySimpleGUI information. Information is posted frequently including release contents, tips & tricks, documentation updates, etc. There have been over 1,000 posts since the project started.

About Me 👋

Hi there! I'm Mike. You'll find me right here, on the PySimpleGUI GitHub, solving problems and continuously pushing PySimpleGUI forward. I've dedicated my days, nights, and weekends to the project and PySimpleGUI users. Our successes are ultimately shared. I'm successful when you're successful.

While I'm a relative newcomer to Python, I've been writing software since the 70s. The majority of my career was spent creating products in Silicon Valley. I bring to PySimpleGUI the same professionalism and dedication as I did to the corporate products I developed. You are my customers now.

Project Goals 🥅

Two of the most important goals of the PySimpleGUI project:

  • Having fun
  • Your success

Fun as a goal on a serious project sounds odd, but it's a serious goal. I find writing these GUI programs to be a lot of fun. One reason is how little time it takes to write a complete solution. If we're not enjoying the process then someone's going to give up.

There is a significant amount of documentation, a cookbook, 100's of demo programs to get you immediately running, a detailed call reference, YouTube videos, online Trinket demos, and more... all working to create... a fun experience.

Your Success is a shared goal. PySimpleGUI was built for developers. You're my peeps. It's been an unexpected reward to see the results of the combined effort of users and PySimpleGUI. Use the documentation & other materials to help build your application. If you run into trouble, help is available by opening on Issue on the PySimpleGUI GitHub. Take a look at the section on Support below.

Educational Resources 📚

PySimpleGUI now has an official Udemy course! Check the header of this readme and the PySimpleGUI documentation for a coupon code. The course can be found at This course is currently the only income source for the PySimpleGUI project other than sponsorships and donations. is easy to remember and is where the documentation is located. You'll find tabs across the top that represent several different documents. The documentation is located on "Read The Docs" so that there is a table of contents for each document and they are easy to search.

There are 100s of pages of written documentation and 100s of example programs that will help you be effective very quickly. Rather than requiring days or weeks of investment to learn a single GUI package, you may be able to complete your project in a single afternoon when using PySimpleGUI.

Example 1 - The One-Shot Window

This type of program is called a "one-shot" window because the window is displayed one time, the values collected, and then it is closed. It doesn't remain open for a long time like you would in a Word Processor.

Anatomy of a Simple PySimpleGUI Program

There are 5 sections to a PySimpleGUI program

import PySimpleGUI as sg                        # Part 1 - The import

# Define the window's contents
layout = [  [sg.Text("What's your name?")],     # Part 2 - The Layout
            [sg.Button('Ok')] ]

# Create the window
window = sg.Window('Window Title', layout)      # Part 3 - Window Defintion
# Display and interact with the Window
event, values =                   # Part 4 - Event loop or call

# Do something with the information gathered
print('Hello', values[0], "! Thanks for trying PySimpleGUI")

# Finish up by removing from the screen
window.close()                                  # Part 5 - Close the Window

The code produces this window

Example 2 - Interactive Window

In this example, our window will remain on the screen until the user closes the window or clicks the Quit button. The main difference between the one-shot window you saw earlier and an interactive window is the addition of an "Event Loop". The Event Loop reads events and inputs from your window. The heart of your application lives in the event loop.

import PySimpleGUI as sg

# Define the window's contents
layout = [[sg.Text("What's your name?")],
          [sg.Text(size=(40,1), key='-OUTPUT-')],
          [sg.Button('Ok'), sg.Button('Quit')]]

# Create the window
window = sg.Window('Window Title', layout)

# Display and interact with the Window using an Event Loop
while True:
    event, values =
    # See if user wants to quit or window was closed
    if event == sg.WINDOW_CLOSED or event == 'Quit':
    # Output a message to the window
    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")

# Finish up by removing from the screen

This is the window that Example 2 produces.

And here's what it looks like after you enter a value into the Input field and click the Ok button.

Let's take a quick look at some of the differences between this example and the one-shot window.

First, you'll notice differences in the layout. Two changes in particular are important. One is the addition of the key parameter to the Input element and one of the Text elements. A key is like a name for an element. Or, in Python terms, it's like a dictionary key. The Input element's key will be used as a dictionary key later in the code.

Another difference is the addition of this Text element:

          [sg.Text(size=(40,1), key='-OUTPUT-')],

There are 2 parameters, the key we already covered. The size parameter defines the size of the element in characters. In this case, we're indicating that this Text element is 40 characters wide, by 1 character high. Notice that there is no text string specified which means it'll be blank. You can easily see this blank row in the window that's created.

We also added a button, "Quit".

The Event Loop has our familiar call.

Following the read is this if statement:

    if event == sg.WINDOW_CLOSED or event == 'Quit':

This code is checking to see if the user closed the window by clicking the "X" or if they clicked the "Quit" button. If either of these happens, then the code will break out of the event loop.

If the window wasn't closed nor the Quit button clicked, then execution continues. The only thing that could have happened is the user clicked the "Ok" button. The last statement in the Event Loop is this one:

    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")

This statement updates the Text element that has the key -OUTPUT- with a string. window['-OUTPUT-'] finds the element with the key -OUTPUT-. That key belongs to our blank Text element. Once that element is returned from the lookup, then its update method is called. Nearly all elements have an update method. This method is used to change the value of the element or to change some configuration of the element.

If we wanted the text to be yellow, then that can be accomplished by adding a text_color parameter to the update method so that it reads:

    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI",

After adding the text_color parameter, this is our new resulting window:

The parameters available for each element are documented in both the call reference documentation as well as the docstrings. PySimpleGUI has extensive documentation to help you understand all of the options available to you. If you lookup the update method for the Text element, you'll find this definition for the call:

As you can see several things can be changed for a Text element. The call reference documentation is a valuable resource that will make programming in PySimpleGUI, uhm, simple.

Jump Start! Get the Demo Programs & Demo Browser 🔎

The over 300 Demo Programs will give you a jump-start and provide many design patterns for you to learn how to use PySimpleGUI and how to integrate PySimpleGUI with other packages. By far the best way to experience these demos is using the Demo Browser. This tool enables you to search, edit and run the Demo Programs.

To get them installed quickly along with the Demo Browser, use pip to install psgdemos:

python -m pip install psgdemos

or if you're in Linux, Mac, etc, that uses python3 instead of python to launch Python:

python3 -m pip install psgdemos

Once installed, launch the demo browser by typing psgdemos from the command line"



Layouts Are Funny LOL! 😆

Your window's layout is a "list of lists" (LOL). Windows are broken down into "rows". Each row in your window becomes a list in your layout. Concatenate together all of the lists and you've got a layout...a list of lists.

Here is the same layout as before with an extra Text element added to each row so that you can more easily see how rows are defined:

layout = [  [sg.Text('Row 1'), sg.Text("What's your name?")],
            [sg.Text('Row 2'), sg.Input()],
            [sg.Text('Row 3'), sg.Button('Ok')] ]

Each row of this layout is a list of elements that will be displayed on that row in your window.

Using lists to define your GUI has some huge advantages over how GUI programming is done using other frameworks. For example, you can use Python's list comprehension to create a grid of buttons in a single line of code.

These 3 lines of code:

import PySimpleGUI as sg

layout = [[sg.Button(f'{row}, {col}') for col in range(4)] for row in range(4)]

event, values = sg.Window('List Comprehensions', layout).read(close=True)

produces this window which has a 4 x 4 grid of buttons:

Recall how "fun" is one of the goals of the project. It's fun to directly apply Python's powerful basic capabilities to GUI problems. Instead of pages of code to create a GUI, it's a few (or often 1) lines of code.

Collapsing Code

It's possible to condense a window's code down to a single line of code. The layout definition, window creation, display, and data collection can all be written in this line of code:

event, values = sg.Window('Window Title', [[sg.Text("What's your name?")],[sg.Input()],[sg.Button('Ok')]]).read(close=True)

The same window is shown and returns the same values as the example showing the sections of a PySimpleGUI program. Being able to do so much with so little enables you to quickly and easily add GUIs to your Python code. If you want to display some data and get a choice from your user, it can be done in a line of code instead of a page of code.

By using short-hand aliases, you can save even more space in your code by using fewer characters. All of the Elements have one or more shorter names that can be used. For example, the Text element can be written simply as T. The Input element can be written as I and the Button as B. Your single-line window code thus becomes:

event, values = sg.Window('Window Title', [[sg.T("What's your name?")],[sg.I()],[sg.B('Ok')]]).read(close=True)

Code Portability

PySimpleGUI is currently capable of running on 4 Python GUI Frameworks. The framework to use is specified using the import statement. Change the import and you'll change the underlying GUI framework. For some programs, no other changes are needed than the import statement to run on a different GUI framework. In the example above, changing the import from PySimpleGUI to PySimpleGUIQt, PySimpleGUIWx, PySimpleGUIWeb will change the framework.

Import StatementResulting Window

Porting GUI code from one framework to another (e.g. moving your code from tkinter to Qt) usually requires a rewrite of your code. PySimpleGUI is designed to enable you to have easy movement between the frameworks. Sometimes some changes are required of you, but the goal is to have highly portable code with minimal changes.

Some features, like a System Tray Icon, are not available on all of the ports. The System Tray Icon feature is available on the Qt and WxPython ports. A simulated version is available on tkinter. There is no support for a System Tray icon in the PySimpleGUIWeb port.

Runtime Environments

PythonPython 3.4+
Operating SystemsWindows, Linux, Mac
HardwareDesktop PCs, Laptops, Raspberry Pi, Android devices running PyDroid3, (both run tkinter in a browser)
GUI Frameworkstkinter, pyside2, WxPython, Remi


Among the more than 200 "Demo Programs", you'll find examples of how to integrate many popular Python packages into your GUI.

Want to embed a Matplotlib drawing into your window? No problem, copy the demo code and instantly have a Matplotlib drawing of your dreams into your GUI.

These packages and more are ready for you to put into your GUI as there are demo programs or a demo repo available for each:

MatplotlibMany types of graphs and plots
OpenCVComputer Vision (often used for AI)
VLCVideo playback
pymunkPhysics engine
psutilSystem environment statistics
prawnReddit API
jsonPySimpleGUI wraps a special API to store "User Settings"
weatherIntegrates with several weather APIs to make weather apps
midoMIDI playback
beautiful soupWeb Scraping (GitHub issue watcher example)

Installing 💾

Two common ways of installing PySimpleGUI:

  1. pip to install from PyPI
  2. Download the file and place in your application's folder

Pip Installing & Upgrading

The current suggested way of invoking the pip command is by running it as a module using Python. Previously the command pip or pip3 was directly onto a command-line / shell. The suggested way

Initial install for Windows:

python -m pip install PySimpleGUI

Initial install for Linux and MacOS:

python3 -m pip install PySimpleGUI

To upgrade using pip, you simply add 2 parameters to the line --upgrade --no-cache-dir.

Upgrade installation on Windows:

python -m pip install --upgrade --no-cache-dir PySimpleGUI

Upgrade for Linux and MacOS:

python3 -m pip install --upgrade --no-cache-dir PySimpleGUI

Single File Installing

PySimpleGUI was created as a single .py file so that it would be very easy for you to install it, even on systems that are not connected to the internet like a Raspberry Pi. It's as simple as placing the file into the same folder as your application that imports it. Python will use your local copy when performing the import.

When installing using just the .py file, you can get it from either PyPI or if you want to run the most recent unreleased version then you'll download it from GitHub.

To install from PyPI, download either the wheel or the .gz file and unzip the file. If you rename the .whl file to .zip you can open it just like any normal zip file. You will find the file in one of the folders. Copy this file to your application's folder and you're done.

The PyPI link for the tkinter version of PySimpleGUI is:

The GitHub repo's latest version can be found here:

Now some of you are thinking, "yea, but, wait, having a single huge source file is a terrible idea". And, yea, sometimes it can be a terrible idea. In this case, the benefits greatly outweighed the downside. Lots of concepts in computer science are tradeoffs or subjective. As much as some would like it to be, not everything is black and white. Many times the answer to a question is "it depends".

Galleries 🎨

Work on a more formal gallery of user-submitted GUIs as well as those found on GitHub is underway but as of this writing it's not complete. There are currently 2 places you can go to see some screenshots in a centralized way. Hopefully, a Wiki or other mechanism can be released soon to do justice to the awesome creations people are making.

User Submitted Gallery

The first is a user submitted screenshots issue located on the GitHub. It's an informal way for people to show off what they've made. It's not ideal, but it was a start.

Massive Scraped GitHub Images

The second is a massive gallery of over 3,000 images scraped from 1,000 projects on GitHub that are reportedly using PySimpleGUI. It's not been hand-filtered and there are plenty of old screenshots that were used in the early documentation. But, you may find something in there that sparks your imagination.

Uses for PySimpleGUI 🔨

The following sections showcase a fraction of the uses for PySimpleGUI. There are over 1,000 projects on GitHub alone that use PySimpleGUI. It's truly amazing how possibilities have opened up for so many people. Many users have spoken about previously attempting to create a GUI in Python and failing, but finally achieving their dreams when they tried PySimpleGUI.

Your First GUI

Of course one of the best uses of PySimpleGUI is getting you into making GUIs for your Python projects. You can start as small as requesting a filename. For this, you only need to make a single call to one of the "high-level functions" called popup. There are all kinds of popups, some collect information.

popup on itself makes a window to display information. You can pass multiple parameters just like a print. If you want to get information, then you will call functions that start with popup_get_ such as popup_get_filename.

Adding a single line to get a filename instead of specifying a filename on the command line can transform your program into one that "normal people" will feel comfortable using.

import PySimpleGUI as sg

filename = sg.popup_get_file('Enter the file you wish to process')
sg.popup('You entered', filename)

This code will display 2 popup windows. One to get the filename, which can be browsed to or pasted into the input box.


The other window will output what is collected.



Rainmeter-Style Windows

imgThe default settings for GUI frameworks don't tend to produce the nicest looking windows. However, with some attention to detail, you can do several things to make windows look attractive. PySimpleGUI makes it easier to manipulate colors and features like removing the title bar. The result is windows that don't look like your typical tkinter windows.

Here is an example of how you can create windows that don't look like your typical tkinter in windows. In this example, the windows have their titlebars removed. The result is windows that look much like those found when using Rainmeter, a desktop widget program.

You can easily set the transparency of a window as well. Here are more examples of desktop widgets in the same Rainmeter style. Some are dim appearing because they are semi-transparent.img

Both of these effects; removing the titlebar and making a window semi-transparent, are achieved by setting 2 parameters when creating the window. This is an example of how PySimpleGUI enables easy access to features. And because PySimpleGUI code is portable across the GUI frameworks, these same parameters work for the other ports such as Qt.

Changing the Window creation call in Example 1 to this line of code produces a similar semi-transparent window:

window = sg.Window('My window', layout, no_titlebar=True, alpha_channel=0.5)


While not specifically written as a game development SDK, PySimpleGUI makes the development of some games quite easy.


This Chess program not only plays chess, but it integrates with the Stockfish chess-playing AI.

Several variants of Minesweeper have been released by users.

Card games work well with PySimpleGUI as manipulating images is simple when using the PySimpleGUI Graph element.

While not specifically written as a game development SDK, PySimpleGUI makes development of some games quite easy.

Media Capture and Playback


Capturing and displaying video from your webcam in a GUI is 4 lines of PySimpleGUI code. Even more impressive is that these 4 lines of code work with the tkinter, Qt, and Web ports. You can display your webcam, in realtime, in a browser using the same code that displays the image using tkinter.

Media playback, audio and video, can also be achieved using the VLC player. A demo application is provided to you so that you have a working example to start from. Everything you see in this readme is available to you as a starting point for your own creations.

Artificial Intelligence


AI and Python have long been a recognized superpower when the two are paired together. What's often missing however is a way for users to interact with these AI algorithms familiarly, using a GUI.

These YOLO demos are a great example of how a GUI can make a tremendous difference in interacting with AI algorithms. Notice two sliders at the bottom of these windows. These 2 sliders change a couple of the parameters used by the YOLO algorithm.

If you were tuning your YOLO demo using only the command line, you would need to set the parameters, once, when you launch the application, see how they perform, stop the application, change the parameters, and finally restart the application with the new parameters.

Contrast those steps against what can be done using a GUI. A GUI enables you to modify these parameters in real-time. You can immediately get feedback on how they are affecting the algorithm.


There are SO many AI programs that have been published that are command-line driven. This in itself isn't a huge hurdle, but it's enough of a "pain in the ass" to type/paste the filename you want to colorize on the command line, run the program, then open the resulting output file in a file viewer.

GUIs have the power to change the user experience, to fill the "GUI Gap". With this colorizer example, the user only needs to supply a folder full of images, and then click on an image to both colorize and display the result.

The program/algorithm to do the colorization was freely available, ready to use. What was missing is the ease of use that a GUI could bring.



Displaying and interacting with data in a GUI is simple with PySimpleGUI. You have several options.

You can use the built-in drawing/graphing capabilities to produce custom graphs. This CPU usage monitor uses the Graph element


Matplotlib is a popular choice with Python users. PySimpleGUI can enable you to embed Matplotlib graphs directly into your GUI window. You can even embed the interactive controls into your window if you want to retain the Matplotlib interactive features.img

Using PySimpleGUI's color themes, you can produce graphs that are a notch above default graphs that most people create in Matplotlib.



The "GUI Gap" mentioned earlier can be easily solved using PySimpleGUI. You don't even need to have the source code to the program you wish to add a GUI onto. A "front-end" GUI is one that collects information that is then passed to a command-line application.

Front-end GUIs are a fantastic way for a programmer to distribute an application that users were reluctant to use previously because they didn't feel comfortable using a command-line interface. These GUIs are your only choice for command-line programs that you don't have access to the source code for.

This example is a front-end for a program called "Jump Cutter". The parameters are collected via the GUI, a command-line is constructed using those parameters, and then the command is executed with the output from the command-line program being routed to the GUI interface. In this example, you can see in yellow the command that was executed.

Raspberry Pi


Because PySimpleGUI is compatible back to Python 3.4, it is capable of creating a GUI for your Raspberry Pi projects. It works particularly well when paired with a touchscreen. You can also use PySimpleGUIWeb to control your Pi if it doesn't have a monitor attached.

Easy Access to Advanced Features


Because it's very easy to access many of the underlying GUI frameworks' features, it's possible to piece together capabilities to create applications that look nothing like those produced using the GUI framework directly.

For example, it's not possible to change the color/look-and-feel of a titlebar using tkinter or the other GUI packages, but with PySimpleGUI it's easy to create windows that appear as if they have a custom titlebar.

Unbelievably, this window is using tkinter to achieve what appears to be something like a screensaver.

On windows, tkinter can completely remove the background from your application. Once again, PySimpleGUI makes accessing these capabilities trivial. Creating a transparent window requires adding a single parameter to the call that creates your Window. One parameter change can result in a simple application with this effect:

You can interact with everything on your desktop, clicking through a full-screen window.


Tired of the default grey GUIs? PySimpleGUI makes it trivial for your window to look nice by making a single call to the theme function. There are over 150 different color themes available for you to choose:


With most GUI frameworks, you must specify the color for every widget you create. PySimpleGUI takes this chore from you and will automatically color the Elements to match your chosen theme.

To use a theme, call the theme function with the name of the theme before creating your window. You can add spaces for readability. To set the theme to "Dark Grey 9":

import PySimpleGUI as sg

sg.theme('dark grey 9')

This single line of code changes the window's appearance entirely:


The theme changed colors of the background, text, input background, input text, and button colors. In other GUI packages, to change color schemes like this, you would need to specify the colors of each widget individually, requiring numerous changes to your code.


Want to share your PySimpleGUI program with friends and family that don't have Python installed on their computer? Try the GUI front-end for PyInstaller that you'll find in the psgcompiler project.

Support 💪

Your first stop should be the documentation and demo programs.

Be sure and install the Demo Browser (instructions in the Cookbook) so that you can search and run the 100s of demo programs.

If you still have a question or need help... no problem... help is available to you, at no cost. Simply file an Issue on the PySimpleGUI GitHub repo and you'll get help.

Nearly all software companies have a form that accompanies bug reports. It's not a bad trade... fill in the form, get free software support. This information helps get you an answer efficiently.

In addition to requesting information such as the version numbers of PySimpleGUI and underlying GUI frameworks, you're also given a checklist of items that may help you solve your problem.

Please fill in the form. It may feel pointless to you. It may feel painful, despite it taking just a moment. It helps get you a solution faster. If it wasn't useful and necessary information to help you get a speedy reply and fix, you wouldn't be asked to fill it out. "Help me help you".

Supporting img

Financial support for the project is greatly appreciated. To be honest, financial help is needed. It's expensive just keeping the lights on. The domain name registrations, a long list of subscriptions for things like Trinket, consulting help, etc., quickly add up to a sizable recurring cost.

PySimpleGUI wasn't inexpensive to create. While a labor of love, it was very laborious over several years, and quite a bit was invested, and continues to be invested, in creating what you see today.

PySimpleGUI has an open-source license and it would be great if it could remain that way. If you or your company (especially if you're using PySimpleGUI in a company) are benefiting financially by using PySimpleGUI, you have the capability of extending the life of the project for you and other users.

Buy Me A Coffee

Buy Me a Coffee is a great way to publicly support developers. It's quick, easy, and your contribution is recorded so that others can see that you're a supporter of PySimpleGUI. You can also choose to make your donation private.

GitHub Sponsoring

The GitHub recurring sponsorship is how you can sponsor the project at varying levels of support on an ongoing basis. It's how many Open Source developers are able to receive corporate level sponsorship.

Your help in financially contributing to the project would be greatly appreciated. Being an Open Source developer is financially challenging. YouTube video creators are able to make a living creating videos. It's not so easy yet for Open Source developers.

Thank you for the Thank You's

To everyone that's helped, in whatever fashion, I'm very very grateful.

Even taking a moment to say "thank you" helps, and a HUGE number of you have done that. It's been an amazing number actually. I value these thanks and find inspiration in the words alone. Every message is a little push forward. It adds a little bit of energy and keeps the whole project's momentum. I'm so very grateful to everyone that's helped in whatever form it's been.

Contributing 👷

While PySimpleGUI is currently licensed under an open-source license, the project itself is structured like a proprietary product. Pull Requests are not accepted.

One of the best ways for you to contribute code is to write and publish applications. Users are inspired by seeing what other users build. Here's a simple set of steps you can take - Create a GitHub repo, post the code, and include a screenshot in your repo's readme file. Then come back to the PySimpleGUI repo and post a screenshot in Issue #10 or in the project's WIKI.

If there is a feature missing that you need or you have an enhancement to suggest, then open an Issue

Special Thanks 🙏

The PySimpleGUI team is tiny and they're all superstars. Every week I've been stunned by what they do. Dream-team is an understatement. Simply put @Chr0nicT, @jason990420, @Snaiel and Mike@PySimpleGUI are PySimpleGUI.

This version of the PySimpleGUI readme wouldn't have come together without the help from @M4cs. He's a fantastic developer and has been a PySimpleGUI supporter since the project's launch. @israel-dryer is another long-term supporter and has written several PySimpleGUI programs that pushed the envelope of the package's capabilities. The unique minesweeper that uses an image for the board was created by Israel. @jason990420 surprised many when he published the first card game using PySimpleGUI that you see pictured above as well as the first minesweeper game made with PySimpleGUI. @Chr0nicT is the youngest developer I've worked with, ever, on projects. This kid shocks me on a regular basis. Ask for a capability, such as the PySimpleGUI GitHub Issues form error checking bot, and it simply happens regardless of the technologies involved. I'm fortunate that we were introduced. Someday he's going to be whisked away, but until then we're all benefiting from his talent. @Snaiel made the Udemy course happen. It wouldn't have been 1/4th of what it is without his amazing skills in video production, course design, marketing brilliance, and web programming. The Japanese version of the readme was greatly improved with help from @okajun35. @nngogol has had a very large impact on the project, also getting involved with PySimpleGUI in the first year of initial release. He wrote a designer, came up with the familiar window[key] lookup syntax, wrote the tools that create the documentation, designed the first set of doc strings as well as tools that generate the online documenation using the PySimpleGUI code itself. PySimpleGUI would not be where it is today were it not for the help of these individuals.

The more than 4,000 GitHub repos that use PySimpleGUI are owed a "Thank You" as well, for it is you that has been the inspiration that fuels this project's engine.

The overseas users that post on Twitter overnight are the spark that starts the day's work on PySimpleGUI. They've been a source of positive energy that gets the development engine started and ready to run every day. As a token of appreciation, this readme file has been translated into Japanese.

PySimpleGUI users have been the best user community an Open Source developer could hope for. I've never seen expressions of gratitude and joy like PySimpleGUI users show on a daily basis.

© Copyright 2021, 2022 PySimpleGUI

Author: PySimpleGUI
Source Code:
License: LGPL-3.0 License

#python #gui 

PySimpleGUI: Python GUIs for Humans

Pyglet: A Cross Platform Windowing and Multimedia Library for Python


pyglet is a cross-platform windowing and multimedia library for Python, intended for developing games and other visually rich applications. It supports windowing, user interface event handling, Joysticks, OpenGL graphics, loading images and videos, and playing sounds and music. pyglet works on Windows, OS X and Linux.

NOTE! The pyglet-1.5-maintenance branch is the current stable release. The master branch contains the the development code for the upcoming 2.0 release, and may be unstable. If you want to do a pull request, please target the pyglet-1.5-maintenance branch where appropriate.

Pyglet has an active developer and user community. If you find a bug or a problem with the documentation, please open an issue. Anyone is welcome to join our discord server where a lot of the development discussion is going on. It's also a great place to ask for help.

Some features of pyglet are:

  • No external dependencies or installation requirements. For most application and game requirements, pyglet needs nothing else besides Python, simplifying distribution and installation. It's easy to package your project with freezers such as PyInstaller.
  • Take advantage of multiple windows and multi-monitor desktops. pyglet allows you to use multiple platform-native windows, and is fully aware of multi-monitor setups for use with fullscreen games.
  • Load images, sound, music and video in almost any format. pyglet can optionally use FFmpeg to play back audio formats such as MP3, OGG/Vorbis and WMA, and video formats such as MPEG2, H.264, H.265, WMV and Xvid. Without FFmpeg, pyglet contains built-in support for standard formats such as wav, png, bmp, and others.
  • pyglet is written entirely in pure Python, and makes use of the ctypes module to interface with system libraries. You can modify the codebase or make a contribution without any second language compilation steps or compiler setup. Despite being pure Python, pyglet has excellent performance thanks to advanced batching for drawing thousands of objects.
  • pyglet is provided under the BSD open-source license, allowing you to use it for both commercial and other open-source projects with very little restriction.


pyglet runs under Python 3.6+. Being written in pure Python, it also works on other Python interpreters such as PyPy. Supported platforms are:

  • Windows 7 or later
  • Mac OS X 10.3 or later
  • Linux, with the following libraries (most recent distributions will have these in a default installation):
    • OpenGL and GLX
    • GDK 2.0+ or Pillow (required for loading images other than PNG and BMP)
    • OpenAL or Pulseaudio (required for playing audio)

Please note that pyglet v1.5 will likely be the last version to support legacy OpenGL. Future releases of pyglet will be targeting OpenGL 3.3+. Previous releases will remain available for download.

Starting with version 1.4, to play compressed audio and video files, you will also need FFmpeg.


pyglet is installable from PyPI:

pip install --upgrade --user pyglet

Installation from source

If you're reading this README from a source distribution, you can install pyglet with:

python install --user

You can also install the latest development version direct from Github using:

pip install --upgrade --user

For local development install pyglet in editable mode:

# with pip
pip install -e .
# with
python develop

There are no compilation steps during the installation; if you prefer, you can simply add this directory to your PYTHONPATH and use pyglet without installing it. You can also copy pyglet directly into your project folder.


A good way to start contributing to a component of pyglet is by its documentation. When studying the code you are going to work with, also read the associated docs. If you don't understand the code with the help of the docs, it is a sign that the docs should be improved.

If you want to contribute to pyglet, we suggest the following:

  • Fork the official repository.
  • Checkout the branch you wish to contribute to (such as pyglet-1.4-maintenance).
  • Apply your changes to your fork.
  • Submit a pull request describing the changes you have made.
  • Alternatively you can create a patch and submit it to the issue tracker.

When making a pull request, check that you have addressed its respective documentation, both within the code docstrings and the programming guide (if applicable). It is very important to all of us that the documentation matches the latest code and vice-versa.

Consequently, an error in the documentation, either because it is hard to understand or because it doesn't match the code, is a bug that deserves to be reported on a ticket.

Building Docs

pip install -r doc/requirements.txt
python build_sphinx

Please check the file in the doc directory for more details.


pyglet makes use of pytest for its test suite.

pip install -r tests/requirements.txt --user
# Only run unittests
pytest tests/unit

Please check the testing section in the development guide for more information about running and writing tests.


pyglet is developed by many individual volunteers, and there is no central point of contact. If you have a question about developing with pyglet, or you wish to contribute, please join the mailing list or the discord server.

For legal issues, please contact Alex Holkner.

Author: pyglet
Source Code:
License: BSD-3-Clause License

#python #gui 

Pyglet: A Cross Platform Windowing and Multimedia Library for Python

Gooey: Turn any Python 3 Console Program into A GUI Application


Turn (almost) any Python 3 Console Program into a GUI application with one line

Quick Start

Installation instructions

The easiest way to install Gooey is via pip

pip install Gooey 

Alternatively, you can install Gooey by cloning the project to your local directory

git clone


python install


Gooey is attached to your code via a simple decorator on whichever method has your argparse declarations (usually main).

from gooey import Gooey

@Gooey      <--- all it takes! :)
def main():
  parser = ArgumentParser(...)
  # rest of code

Different styling and functionality can be configured by passing arguments into the decorator.

# options
@Gooey(advanced=Boolean,          # toggle whether to show advanced config or not 
       language=language_string,  # Translations configurable via json
       auto_start=True,           # skip config screens all together
       target=executable_cmd,     # Explicitly set the subprocess executable arguments
       program_name='name',       # Defaults to script name
       program_description,       # Defaults to ArgParse Description
       default_size=(610, 530),   # starting size of the GUI
       required_cols=1,           # number of columns in the "Required" section
       optional_cols=2,           # number of columns in the "Optional" section
       dump_build_config=False,   # Dump the JSON Gooey uses to configure itself
       load_build_config=None,    # Loads a JSON Gooey-generated configuration
       monospace_display=False)   # Uses a mono-spaced font in the output screen
def main():
  parser = ArgumentParser(...)
  # rest of code

See: How does it Work section for details on each option.

Gooey will do its best to choose sensible widget defaults to display in the GUI. However, if more fine tuning is desired, you can use the drop-in replacement GooeyParser in place of ArgumentParser. This lets you control which widget displays in the GUI. See: GooeyParser

from gooey import Gooey, GooeyParser

def main():
  parser = GooeyParser(description="My Cool GUI Program!") 
  parser.add_argument('Filename', widget="FileChooser")
  parser.add_argument('Date', widget="DateChooser")


Gooey downloaded and installed? Great! Wanna see it in action? Head over the the Examples Repository to download a few ready-to-go example scripts. They'll give you a quick tour of all Gooey's various layouts, widgets, and features.

Direct Download

What is it?

Gooey converts your Console Applications into end-user-friendly GUI applications. It lets you focus on building robust, configurable programs in a familiar way, all without having to worry about how it will be presented to and interacted with by your average user.


Because as much as we love the command prompt, the rest of the world looks at it like an ugly relic from the early '80s. On top of that, more often than not programs need to do more than just one thing, and that means giving options, which previously meant either building a GUI, or trying to explain how to supply arguments to a Console Application. Gooey was made to (hopefully) solve those problems. It makes programs easy to use, and pretty to look at!

Who is this for?

If you're building utilities for yourself, other programmers, or something which produces a result that you want to capture and pipe over to another console application (e.g. *nix philosophy utils), Gooey probably isn't the tool for you. However, if you're building 'run and done,' around-the-office-style scripts, things that shovel bits from point A to point B, or simply something that's targeted at a non-programmer, Gooey is the perfect tool for the job. It lets you build as complex of an application as your heart desires all while getting the GUI side for free.

How does it work?

Gooey is attached to your code via a simple decorator on whichever method has your argparse declarations.

def my_run_func():
  parser = ArgumentParser(...)
  # rest of code

At run-time, it parses your Python script for all references to ArgumentParser. (The older optparse is currently not supported.) These references are then extracted, assigned a component type based on the 'action' they provide, and finally used to assemble the GUI.


Gooey does its best to choose sensible defaults based on the options it finds. Currently, ArgumentParser._actions are mapped to the following WX components.

Parser ActionWidgetExample
Mutually Exclusive GroupRadioGroup
choice                                             DropDown


If the above defaults aren't cutting it, you can control the exact widget type by using the drop-in ArgumentParser replacement GooeyParser. This gives you the additional keyword argument widget, to which you can supply the name of the component you want to display. Best part? You don't have to change any of your argparse code to use it. Drop it in, and you're good to go.


from argparse import ArgumentParser

def main(): 
    parser = ArgumentParser(description="My Cool Gooey App!")
    parser.add_argument('filename', help="name of the file to process") 

Given then above, Gooey would select a normal TextField as the widget type like this:

However, by dropping in GooeyParser and supplying a widget name, you can display a much more user friendly FileChooser

from gooey import GooeyParser

def main(): 
    parser = GooeyParser(description="My Cool Gooey App!")
    parser.add_argument('filename', help="name of the file to process", widget='FileChooser') 

Custom Widgets:

DirChooser, FileChooser, MultiFileChooser, FileSaver, MultiFileSaver


Please note that for both of these widgets the values passed to the application will always be in ISO format while localized values may appear in some parts of the GUI depending on end-user settings.


The default InlineCheck box can look less than ideal if a large help text block is present. BlockCheckbox moves the text block to the normal position and provides a short-form block_label for display next to the control. Use gooey_options.checkbox_label to control the label text






Gooey is international ready and easily ported to your host language. Languages are controlled via an argument to the Gooey decorator.

def main(): 

All program text is stored externally in json files. So adding new language support is as easy as pasting a few key/value pairs in the gooey/languages/ directory.

Thanks to some awesome contributors, Gooey currently comes pre-stocked with over 18 different translations!

Want to add another one? Submit a pull request!

Global Configuration

Just about everything in Gooey's overall look and feel can be customized by passing arguments to the decorator.

encodingText encoding to use when displaying characters (default: 'utf-8')
use_legacy_titlesRewrites the default argparse group name from "Positional" to "Required". This is primarily for retaining backward compatibility with previous versions of Gooey (which had poor support/awareness of groups and did its own naive bucketing of arguments).
advancedToggles whether to show the 'full' configuration screen, or a simplified version
auto_startSkips the configuration all together and runs the program immediately
languageTells Gooey which language set to load from the gooey/languages directory.
targetTells Gooey how to re-invoke itself. By default Gooey will find python, but this allows you to specify the program (and arguments if supplied).
suppress_gooey_flagShould be set when using a custom target. Prevent Gooey from injecting additional CLI params
program_nameThe name displayed in the title bar of the GUI window. If not supplied, the title defaults to the script name pulled from sys.argv[0].
program_descriptionSets the text displayed in the top panel of the Settings screen. Defaults to the description pulled from ArgumentParser.
default_sizeInitial size of the window
fullscreenstart Gooey in fullscreen mode
required_colsControls how many columns are in the Required Arguments section 
:warning: Deprecation notice: See Layout Customization for modern layout controls
optional_colsControls how many columns are in the Optional Arguments section 
:warning: Deprecation notice: See Layout Customization for modern layout controls
dump_build_configSaves a json copy of its build configuration on disk for reuse/editing
load_build_configLoads a json copy of its build configuration from disk
monospace_displayUses a mono-spaced font in the output screen 
:warning: Deprecation notice: See Layout Customization for modern font configuration
image_dirPath to the directory in which Gooey should look for custom images/icons
language_dirPath to the directory in which Gooey should look for custom languages files
disable_stop_buttonDisable the Stop button when running
show_stop_warningDisplays a warning modal before allowing the user to force termination of your program
force_stop_is_errorToggles whether an early termination by the shows the success or error screen
show_success_modalToggles whether or not to show a summary modal after a successful run
show_failure_modalToggles whether or not to show a summary modal on failure
show_restart_buttonToggles whether or not to show the restart button at the end of execution
run_validatorsControls whether or not to have Gooey perform validation before calling your program
poll_external_updates(Experimental!) When True, Gooey will call your code with a gooey-seed-ui CLI argument and use the response to fill out dynamic values in the UI (See: Using Dynamic Values)
use_cmd_argsSubstitute any command line arguments provided at run time for the default values specified in the Gooey configuration
return_to_configWhen True, Gooey will return to the configuration settings window upon successful run
progress_regexA text regex used to pattern match runtime progress information. See: Showing Progress for a detailed how-to
progress_exprA python expression applied to any matches found via the progress_regex. See: Showing Progress for a detailed how-to
hide_progress_msgOption to hide textual progress updates which match the progress_regex. See: Showing Progress for a detailed how-to
disable_progress_bar_animationDisable the progress bar
timing_optionsThis contains the options for displaying time remaining and elapsed time, to be used with progress_regex and progress_expr. Elapsed / Remaining Time. Contained as a dictionary with the options show_time_remaining and hide_time_remaining_on_complete. Eg: timing_options={'show_time_remaining':True,'hide_time_remaining_on_complete':True}
show_time_remainingDisable the time remaining text see Elapsed / Remaining Time
hide_time_remaining_on_completeHide time remaining on complete screen see Elapsed / Remaining Time
requires_shellControls whether or not the shell argument is used when invoking your program. More info here
shutdown_signalSpecifies the signal to send to the child process when the stop button is pressed. See Gracefully Stopping in the docs for more info.

Sets the "navigation" style of Gooey's top level window. 

sidebar_title Controls the heading title above the SideBar's navigation pane. Defaults to: "Actions"
show_sidebarShow/Hide the sidebar in when navigation mode == SIDEBAR
body_bg_colorHEX value of the main Gooey window
header_bg_colorHEX value of the header background
header_heightheight in pixels of the header
header_show_titleShow/Hide the header title
header_show_subtitleShow/Hide the header subtitle
footer_bg_colorHEX value of the Footer background
sidebar_bg_colorHEX value of the Sidebar's background
terminal_panel_colorHEX value of the terminal's panel
terminal_font_colorHEX value of the font displayed in Gooey's terminal
terminal_font_familyName of the Font Family to use in the terminal
terminal_font_weightWeight of the font (constants.FONTWEIGHT_NORMAL, constants.FONTWEIGHT_XXX)
terminal_font_sizePoint size of the font displayed in the terminal
error_colorHEX value of the text displayed when a validation error occurs
richtext_controlsSwitch on/off the console support for terminal control sequences (limited support for font weight and color). Defaults to : False. See docs for additional details
menusShow custom menu groups and items (see: Menus
clear_before_runWhen true, previous output will be cleared from the terminal when running program again

Layout Customization

You can achieve fairly flexible layouts with Gooey by using a few simple customizations.

At the highest level, you have several overall layout options controllable via various arguments to the Gooey decorator.


Grouping Inputs

By default, if you're using Argparse with Gooey, your inputs will be split into two buckets: positional and optional. However, these aren't always the most descriptive groups to present to your user. You can arbitrarily bucket inputs into logic groups and customize the layout of each.

With argparse this is done via add_argument_group()

parser = ArgumentParser()
search_group = parser.add_argument_group(
    "Search Options", 
    "Customize the search options"

You can add arguments to the group as normal

    help='Base search string'

Which will display them as part of the group within the UI.

Run Modes

Gooey has a handful of presentation modes so you can tailor its layout to your content type and user's level or experience.


The default view is the "full" or "advanced" configuration screen. It has two different layouts depending on the type of command line interface it's wrapping. For most applications, the flat layout will be the one to go with, as its layout matches best to the familiar CLI schema of a primary command followed by many options (e.g. Curl, FFMPEG).

On the other side is the Column Layout. This one is best suited for CLIs that have multiple paths or are made up of multiple little tools each with their own arguments and options (think: git). It displays the primary paths along the left column, and their corresponding arguments in the right. This is a great way to package a lot of varied functionality into a single app.

Both views present each action in the Argument Parser as a unique GUI component. It makes it ideal for presenting the program to users which are unfamiliar with command line options and/or Console Programs in general. Help messages are displayed along side each component to make it as clear as possible which each widget does.

Setting the layout style:

Currently, the layouts can't be explicitly specified via a parameter (on the TODO!). The layouts are built depending on whether or not there are subparsers used in your code base. So, if you want to trigger the Column Layout, you'll need to add a subparser to your argparse code.

It can be toggled via the advanced parameter in the Gooey decorator.

def main():
    # rest of code   


The basic view is best for times when the user is familiar with Console Applications, but you still want to present something a little more polished than a simple terminal. The basic display is accessed by setting the advanced parameter in the gooey decorator to False.

def main():
    # rest of code  

No Config

No Config pretty much does what you'd expect: it doesn't show a configuration screen. It hops right to the display section and begins execution of the host program. This is the one for improving the appearance of little one-off scripts.

To use this mode, set auto_start=True in the Gooey decorator.

def main (): 



Added 1.0.2

You can add a Menu Bar to the top of Gooey with customized menu groups and items.

Menus are specified on the main @Gooey decorator as a list of maps.

@Gooey(menu=[{}, {}, ...])

Each map is made up of two key/value pairs

  1. name - the name for this menu group
  2. items - the individual menu items within this group

You can have as many menu groups as you want. They're passed as a list to the menu argument on the @Gooey decorator.

@Gooey(menu=[{'name': 'File', 'items: []},
             {'name': 'Tools', 'items': []},
             {'name': 'Help', 'items': []}])

Individual menu items in a group are also just maps of key / value pairs. Their exact key set varies based on their type, but two keys will always be present:

  • type - this controls the behavior that will be attached to the menu item as well as the keys it needs specified
  • menuTitle - the name for this MenuItem

Currently, three types of menu options are supported:

  • AboutDialog
  • MessageDialog
  • Link
  • HtmlDialog

About Dialog is your run-of-the-mill About Dialog. It displays program information such as name, version, and license info in a standard native AboutBox.


  • name - (optional)
  • description - (optional)
  • version - (optional)
  • copyright - (optional)
  • license - (optional)
  • website - (optional)
  • developer - (optional)


    'type': 'AboutDialog',
    'menuTitle': 'About',
    'name': 'Gooey Layout Demo',
    'description': 'An example of Gooey\'s layout flexibility',
    'version': '1.2.1',
    'copyright': '2018',
    'website': '',
    'developer': '',
    'license': 'MIT'

MessageDialog is a generic informational dialog box. You can display anything from small alerts, to long-form informational text to the user.


  • message - (required) the text to display in the body of the modal
  • caption - (optional) the caption in the title bar of the modal


    'type': 'MessageDialog',
    'menuTitle': 'Information',
    'message': 'Hey, here is some cool info for ya!',
    'caption': 'Stuff you should know'

Link is for sending the user to an external website. This will spawn their default browser at the URL you specify.


  • url - (required) - the fully qualified URL to visit


    'type': 'Link',
    'menuTitle': 'Visit Out Site',
    'url': ''

HtmlDialog gives you full control over what's displayed in the message dialog (bonus: people can copy/paste text from this one!).


  • caption - (optional) the caption in the title bar of the modal
  • html - (required) the html you want displayed in the dialog. Note: only a small subset of HTML is supported. See the WX docs for more info.


    'type': 'HtmlDialog',
    'menuTitle': 'Fancy Dialog!',
    'caption': 'Demo of the HtmlDialog',
    'html': '''
    <body bgcolor="white">
        <img src=/path/to/your/image.png" /> 
        <h1>Hello world!</h1> 
        <p><font color="red">Lorem ipsum dolor sit amet, consectetur</font></p>

A full example:

Two menu groups ("File" and "Help") with four menu items between them.

    program_name='Advanced Layout Groups',
        'name': 'File',
        'items': [{
                'type': 'AboutDialog',
                'menuTitle': 'About',
                'name': 'Gooey Layout Demo',
                'description': 'An example of Gooey\'s layout flexibility',
                'version': '1.2.1',
                'copyright': '2018',
                'website': '',
                'developer': '',
                'license': 'MIT'
            }, {
                'type': 'MessageDialog',
                'menuTitle': 'Information',
                'caption': 'My Message',
                'message': 'I am demoing an informational dialog!'
            }, {
                'type': 'Link',
                'menuTitle': 'Visit Our Site',
                'url': ''
        'name': 'Help',
        'items': [{
            'type': 'Link',
            'menuTitle': 'Documentation',
            'url': ''

Dynamic Validation

:warning: Note! This functionality is experimental and likely to be unstable. Its API may be changed or removed altogether. Feedback/thoughts on this feature is welcome and encouraged!

:warning: See Release Notes for guidance on upgrading from 1.0.8 to 1.2.0

Before passing the user's inputs to your program, Gooey can optionally run a special pre-flight validation to check that all arguments pass your specified validations.

How does it work?

Gooey piggy backs on the type parameter available to most Argparse Argument types.

parser.add_argument('--some-number', type=int)
parser.add_argument('--some-number', type=float)

In addition to simple builtins like int and float, you can supply your own function to the type parameter to vet the incoming values.

def must_be_exactly_ten(value): 
    number = int(value) 
    if number == 10:
        return number
        raise TypeError("Hey! you need to provide exactly the number 10!")
def main(): 
    parser = ArgumentParser()
    parser.add_argument('--ten', type=must_be_exactly_ten)

How to enable the pre-flight validation

By default, Gooey won't run the validation. Why? This feature is fairly experimental and does a lot of intense Monkey Patching behind the scenes. As such, it's currently opt-in.

You enable to validation by telling Gooey you'd like to subscribe to the VALIDATE_FORM event.

from gooey import Gooey, Events 

def main(): 

Now, when you run Gooey, before it invokes your main program, it'll send a separate pre-validation check and record any issues raised from your type functions.

Full Code Example

from gooey import Gooey, Events
from argparse import ArgumentParser

def must_be_exactly_ten(value):
    number = int(value)
    if number == 10:
        return number
        raise TypeError("Hey! you need to provide exactly the number 10!")

@Gooey(program_name='Validation Example', use_events=[Events.VALIDATE_FORM])
def main():
    parser = ArgumentParser(description="Checkout this validation!")
    parser.add_argument('--ten', metavar='This field should be 10', type=must_be_exactly_ten)
    args = parser.parse_args()

Lifecycle Events and UI control

:warning: Note! This functionality is experimental. Its API may be changed or removed altogether. Feedback on this feature is welcome and encouraged!

As of 1.2.0, Gooey now exposes coarse grain lifecycle hooks to your program. This means you can now take additional follow-up actions in response to successful runs or failures and even control the current state of the UI itself!

Currently, two primary hooks are exposed:

  • on_success
  • on_error

These fire exactly when you'd expect: after your process has completed.

Anatomy of an lifecycle handler:

Both on_success and on_error have the same type signature.

from typing import Mapping, Any, Optional
from gooey.types import PublicGooeyState  

def on_success(args: Mapping[str, Any], state: PublicGooeyState) -> Optional[PublicGooeyState]:
    You can do anything you want in the handler including 
    returning an updated UI state for your next run!   
    return state
def on_error(args: Mapping[str, Any], state: PublicGooeyState) -> Optional[PublicGooeyState]:
    You can do anything you want in the handler including 
    returning an updated UI state for your next run!   
    return state    
  • args This is the parsed Argparse object (e.g. the output of parse_args()). This will be a mapping of the user's arguments as existed when your program was invoked.
  • state This is the current state of Gooey's UI. If your program uses subparsers, this currently just lists the state of the active parser/form. Whatever updated version of this state you return will be reflected in the UI!

Attaching the handlers:

Handlers are attached when instantiating the GooeyParser.

parser = GooeyParser(

Subscribing to the lifecycle events

Just like Validation, these lifecycle events are opt-in. Pass the event you'd like to subscribe to into the use_events Gooey decorator argument.

from gooey import Gooey, Events 

@Gooey(use_events=[Events.ON_SUCCESS, Events.ON_ERROR])
def main(): 

Showing Progress

Giving visual progress feedback with Gooey is easy! If you're already displaying textual progress updates, you can tell Gooey to hook into that existing output in order to power its Progress Bar.

For simple cases, output strings which resolve to a numeric representation of the completion percentage (e.g. Progress 83%) can be pattern matched and turned into a progress bar status with a simple regular expression (e.g. @Gooey(progress_regex=r"^progress: (\d+)%$")).

For more complicated outputs, you can pass in a custom evaluation expression (progress_expr) to transform regular expression matches as needed.

Output strings which satisfy the regular expression can be hidden from the console via the hide_progress_msg parameter (e.g. @Gooey(progress_regex=r"^progress: (\d+)%$", hide_progress_msg=True).

Regex and Processing Expression

@Gooey(progress_regex=r"^progress: (?P<current>\d+)/(?P<total>\d+)$",
       progress_expr="current / total * 100")

Program Output:

progress: 1/100
progress: 2/100
progress: 3/100

There are lots of options for telling Gooey about progress as your program is running. Checkout the Gooey Examples repository for more detailed usage and examples!

Elapsed / Remaining Time

Gooey also supports tracking elapsed / remaining time when progress is used! This is done in a similar manner to that of the project tqdm. This can be enabled with timing_options, the timing_options argument takes in a dictionary with the keys show_time_remaining and hide_time_remaining_on_complete. The default behavior is True for show_time_remaining and False for hide_time_remaining_on_complete. This will only work when progress_regex and progress_expr are used.

@Gooey(progress_regex=r"^progress: (?P<current>\d+)/(?P<total>\d+)$",
       progress_expr="current / total * 100",
       timing_options = {

Customizing Icons

Gooey comes with a set of six default icons. These can be overridden with your own custom images/icons by telling Gooey to search additional directories when initializing. This is done via the image_dir argument to the Gooey decorator.

@Gooey(program_name='Custom icon demo', image_dir='/path/to/my/image/directory')
def main():
    # rest of program

Images are discovered by Gooey based on their filenames. So, for example, in order to supply a custom configuration icon, simply place an image with the filename config_icon.png in your images directory. These are the filenames which can be overridden:

  • program_icon.png
  • success_icon.png
  • running_icon.png
  • loading_icon.gif
  • config_icon.png
  • error_icon.png


Thanks to some awesome contributors, packaging Gooey as an executable is super easy.

The tl;dr pyinstaller version is to drop this build.spec into the root directory of your application. Edit its contents so that the APPPNAME and name are relevant to your project and the pathex value points to your applications root, then execute pyinstaller -F --windowed build.spec to bundle your app into a ready-to-go executable.

Detailed step by step instructions can be found here.


Flat LayoutColumn LayoutSuccess ScreenError ScreenWarning Dialog
Custom GroupsTabbed GroupsTabbed NavigationSidebar NavigationInput Validation

Wanna help?

Code, translation, documentation, or graphics? All pull requests are welcome. Just make sure to checkout the contributing guidelines first.

Author: chriskiehl
Source Code:
License: MIT License

#python #gui 

Gooey: Turn any Python 3 Console Program into A GUI Application

Eel: A Little Python Library for Making Simple HTML/JS GUI Apps


Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.

Eel hosts a local webserver, then lets you annotate functions in Python so that they can be called from Javascript, and vice versa.

Eel is designed to take the hassle out of writing short and simple GUI applications. If you are familiar with Python and web development, probably just jump to this example which picks random file names out of the given folder (something that is impossible from a browser).


There are several options for making GUI apps in Python, but if you want to use HTML/JS (in order to use jQueryUI or Bootstrap, for example) then you generally have to write a lot of boilerplate code to communicate from the Client (Javascript) side to the Server (Python) side.

The closest Python equivalent to Electron (to my knowledge) is cefpython. It is a bit heavy weight for what I wanted.

Eel is not as fully-fledged as Electron or cefpython - it is probably not suitable for making full blown applications like Atom - but it is very suitable for making the GUI equivalent of little utility scripts that you use internally in your team.

For some reason many of the best-in-class number crunching and maths libraries are in Python (Tensorflow, Numpy, Scipy etc) but many of the best visualization libraries are in Javascript (D3, THREE.js etc). Hopefully Eel makes it easy to combine these into simple utility apps for assisting your development.

Join Eel's users and maintainers on Discord, if you like.


Install from pypi with pip:

pip install eel

To include support for HTML templating, currently using Jinja2:

pip install eel[jinja2]


Directory Structure

An Eel application will be split into a frontend consisting of various web-technology files (.html, .js, .css) and a backend consisting of various Python scripts.

All the frontend files should be put in a single directory (they can be further divided into folders inside this if necessary).     <-- Python scripts
static_web_folder/      <-- Web folder

Starting the app

Suppose you put all the frontend files in a directory called web, including your start page main.html, then the app is started like this;

import eel

This will start a webserver on the default settings (http://localhost:8000) and open a browser to http://localhost:8000/main.html.

If Chrome or Chromium is installed then by default it will open in that in App Mode (with the --app cmdline flag), regardless of what the OS's default browser is set to (it is possible to override this behaviour).

App options

Additional options can be passed to eel.start() as keyword arguments.

Some of the options include the mode the app is in (e.g. 'chrome'), the port the app runs on, the host name of the app, and adding additional command line flags.

As of Eel v0.12.0, the following options are available to start():

  • mode, a string specifying what browser to use (e.g. 'chrome', 'electron', 'edge', 'custom'). Can also be None or False to not open a window. Default: 'chrome'
  • host, a string specifying what hostname to use for the Bottle server. Default: 'localhost')
  • port, an int specifying what port to use for the Bottle server. Use 0 for port to be picked automatically. Default: 8000.
  • block, a bool saying whether or not the call to start() should block the calling thread. Default: True
  • jinja_templates, a string specifying a folder to use for Jinja2 templates, e.g. my_templates. Default: None
  • cmdline_args, a list of strings to pass to the command to start the browser. For example, we might add extra flags for Chrome; eel.start('main.html', mode='chrome-app', port=8080, cmdline_args=['--start-fullscreen', '--browser-startup-dialog']). Default: []
  • size, a tuple of ints specifying the (width, height) of the main window in pixels Default: None
  • position, a tuple of ints specifying the (left, top) of the main window in pixels Default: None
  • geometry, a dictionary specifying the size and position for all windows. The keys should be the relative path of the page, and the values should be a dictionary of the form {'size': (200, 100), 'position': (300, 50)}. Default: {}
  • close_callback, a lambda or function that is called when a websocket to a window closes (i.e. when the user closes the window). It should take two arguments; a string which is the relative path of the page that just closed, and a list of other websockets that are still open. Default: None
  • app, an instance of Bottle which will be used rather than creating a fresh one. This can be used to install middleware on the instance before starting eel, e.g. for session management, authentication, etc.
  • shutdown_delay, timer configurable for Eel's shutdown detection mechanism, whereby when any websocket closes, it waits shutdown_delay seconds, and then checks if there are now any websocket connections. If not, then Eel closes. In case the user has closed the browser and wants to exit the program. By default, the value of shutdown_delay is 1.0 second

Exposing functions

In addition to the files in the frontend folder, a Javascript library will be served at /eel.js. You should include this in any pages:

<script type="text/javascript" src="/eel.js"></script>

Including this library creates an eel object which can be used to communicate with the Python side.

Any functions in the Python code which are decorated with @eel.expose like this...

def my_python_function(a, b):
    print(a, b, a + b)

...will appear as methods on the eel object on the Javascript side, like this...

console.log("Calling Python...");
eel.my_python_function(1, 2); // This calls the Python function that was decorated

Similarly, any Javascript functions which are exposed like this...

function my_javascript_function(a, b, c, d) {
  if (a < b) {
    console.log(c * d);

can be called from the Python side like this...

print('Calling Javascript...')
eel.my_javascript_function(1, 2, 3, 4)  # This calls the Javascript function

The exposed name can also be overridden by passing in a second argument. If your app minifies JavaScript during builds, this may be necessary to ensure that functions can be resolved on the Python side:

eel.expose(someFunction, "my_javascript_function");

When passing complex objects as arguments, bear in mind that internally they are converted to JSON and sent down a websocket (a process that potentially loses information).

Eello, World!

See full example in: examples/01 - hello_world

Putting this together into a Hello, World! example, we have a short HTML page, web/hello.html:

<!DOCTYPE html>
    <title>Hello, World!</title>

    <!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
    <script type="text/javascript" src="/eel.js"></script>
    <script type="text/javascript">
      eel.expose(say_hello_js); // Expose this function to Python
      function say_hello_js(x) {
        console.log("Hello from " + x);

      say_hello_js("Javascript World!");
      eel.say_hello_py("Javascript World!"); // Call a Python function

    Hello, World!

and a short Python script

import eel

# Set web files folder and optionally specify which file types to check for eel.expose()
#   *Default allowed_extensions are: ['.js', '.html', '.txt', '.htm', '.xhtml']
eel.init('web', allowed_extensions=['.js', '.html'])

@eel.expose                         # Expose this function to Javascript
def say_hello_py(x):
    print('Hello from %s' % x)

say_hello_py('Python World!')
eel.say_hello_js('Python World!')   # Call a Javascript function

eel.start('hello.html')             # Start (this blocks and enters loop)

If we run the Python script (python, then a browser window will open displaying hello.html, and we will see...

Hello from Python World!
Hello from Javascript World! the terminal, and...

Hello from Javascript World!
Hello from Python World! the browser console (press F12 to open).

You will notice that in the Python code, the Javascript function is called before the browser window is even started - any early calls like this are queued up and then sent once the websocket has been established.

Return values

While we want to think of our code as comprising a single application, the Python interpreter and the browser window run in separate processes. This can make communicating back and forth between them a bit of a mess, especially if we always had to explicitly send values from one side to the other.

Eel supports two ways of retrieving return values from the other side of the app, which helps keep the code concise.

To prevent hanging forever on the Python side, a timeout has been put in place for trying to retrieve values from the JavaScript side, which defaults to 10000 milliseconds (10 seconds). This can be changed with the _js_result_timeout parameter to eel.init. There is no corresponding timeout on the JavaScript side.


When you call an exposed function, you can immediately pass a callback function afterwards. This callback will automatically be called asynchrounously with the return value when the function has finished executing on the other side.

For example, if we have the following function defined and exposed in Javascript:

function js_random() {
  return Math.random();

Then in Python we can retrieve random values from the Javascript side like so:

def print_num(n):
    print('Got this from Javascript:', n)

# Call Javascript function, and pass explicit callback function

# Do the same with an inline lambda as callback
eel.js_random()(lambda n: print('Got this from Javascript:', n))

(It works exactly the same the other way around).

Synchronous returns

In most situations, the calls to the other side are to quickly retrieve some piece of data, such as the state of a widget or contents of an input field. In these cases it is more convenient to just synchronously wait a few milliseconds then continue with your code, rather than breaking the whole thing up into callbacks.

To synchronously retrieve the return value, simply pass nothing to the second set of brackets. So in Python we would write:

n = eel.js_random()()  # This immediately returns the value
print('Got this from Javascript:', n)

You can only perform synchronous returns after the browser window has started (after calling eel.start()), otherwise obviously the call will hang.

In Javascript, the language doesn't allow us to block while we wait for a callback, except by using await from inside an async function. So the equivalent code from the Javascript side would be:

async function run() {
  // Inside a function marked 'async' we can use the 'await' keyword.

  let n = await eel.py_random()(); // Must prefix call with 'await', otherwise it's the same syntax
  console.log("Got this from Python: " + n);


Asynchronous Python

Eel is built on Bottle and Gevent, which provide an asynchronous event loop similar to Javascript. A lot of Python's standard library implicitly assumes there is a single execution thread - to deal with this, Gevent can "monkey patch" many of the standard modules such as time. This monkey patching is done automatically when you call import eel. If you need monkey patching you should import gevent.monkey and call gevent.monkey.patch_all() before you import eel. Monkey patching can interfere with things like debuggers so should be avoided unless necessary.

For most cases you should be fine by avoiding using time.sleep() and instead using the versions provided by gevent. For convenience, the two most commonly needed gevent methods, sleep() and spawn() are provided directly from Eel (to save importing time and/or gevent as well).

In this example...

import eel

def my_other_thread():
    while True:
        print("I'm a thread")
        eel.sleep(1.0)                  # Use eel.sleep(), not time.sleep()


eel.start('main.html', block=False)     # Don't block on this call

while True:
    print("I'm a main loop")
    eel.sleep(1.0)                      # Use eel.sleep(), not time.sleep()

...we would then have three "threads" (greenlets) running;

  1. Eel's internal thread for serving the web folder
  2. The my_other_thread method, repeatedly printing "I'm a thread"
  3. The main Python thread, which would be stuck in the final while loop, repeatedly printing "I'm a main loop"

Building distributable binary with PyInstaller

If you want to package your app into a program that can be run on a computer without a Python interpreter installed, you should use PyInstaller.

  1. Configure a virtualenv with desired Python version and minimum necessary Python packages
  2. Install PyInstaller pip install PyInstaller
  3. In your app's folder, run python -m eel [your_main_script] [your_web_folder] (for example, you might run python -m eel web)
  4. This will create a new folder dist/
  5. Valid PyInstaller flags can be passed through, such as excluding modules with the flag: --exclude module_name. For example, you might run python -m eel web --exclude win32com --exclude numpy --exclude cryptography
  6. When happy that your app is working correctly, add --onefile --noconsole flags to build a single executable file

Consult the documentation for PyInstaller for more options.

Microsoft Edge

For Windows 10 users, Microsoft Edge (eel.start(.., mode='edge')) is installed by default and a useful fallback if a preferred browser is not installed. See the examples:

Author: ChrisKnott
Source Code:
License: MIT License

#python #gui 

Eel: A Little Python Library for Making Simple HTML/JS GUI Apps
Sean Robertson

Sean Robertson


iced: A cross-platform GUI library for Rust, inspired by Elm


A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm.



iced is currently experimental software. Take a look at the roadmap, check out the issues, and feel free to contribute!


Add iced as a dependency in your Cargo.toml:

iced = "0.3"

iced moves fast and the master branch can contain breaking changes! If you want to learn about a specific release, check out the release list.


Inspired by The Elm Architecture, iced expects you to split user interfaces into four different concepts:

  • State — the state of your application
  • Messages — user interactions or meaningful events that you care about
  • View logic — a way to display your state as widgets that may produce messages on user interaction
  • Update logic — a way to react to messages and update your state

We can build something to see how this works! Let's say we want a simple counter that can be incremented and decremented using two buttons.

We start by modelling the state of our application:

use iced::button;

struct Counter {
    // The counter value
    value: i32,

    // The local state of the two buttons
    increment_button: button::State,
    decrement_button: button::State,

Next, we need to define the possible user interactions of our counter: the button presses. These interactions are our messages:

#[derive(Debug, Clone, Copy)]
pub enum Message {

Now, let's show the actual counter by putting it all together in our view logic:

use iced::{Button, Column, Text};

impl Counter {
    pub fn view(&mut self) -> Column<Message> {
        // We use a column: a simple vertical layout
                // The increment button. We tell it to produce an
                // `IncrementPressed` message when pressed
                Button::new(&mut self.increment_button, Text::new("+"))
                // We show the value of the counter here
                // The decrement button. We tell it to produce a
                // `DecrementPressed` message when pressed
                Button::new(&mut self.decrement_button, Text::new("-"))

Finally, we need to be able to react to any produced messages and change our state accordingly in our update logic:

impl Counter {
    // ...

    pub fn update(&mut self, message: Message) {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            Message::DecrementPressed => {
                self.value -= 1;

And that's everything! We just wrote a whole user interface. iced is now able to:

  1. Take the result of our view logic and layout its widgets.
  2. Process events from our system and produce messages for our update logic.
  3. Draw the resulting user interface.

Browse the documentation and the examples to learn more!

Implementation details

iced was originally born as an attempt at bringing the simplicity of Elm and The Elm Architecture into Coffee, a 2D game engine I am working on.

The core of the library was implemented during May 2019 in this pull request. The first alpha version was eventually released as a renderer-agnostic GUI library. The library did not provide a renderer and implemented the current tour example on top of ggez, a game library.

Since then, the focus has shifted towards providing a batteries-included, end-user-oriented GUI library, while keeping the ecosystem modular:

iced ecosystem 



This occurs when the selected built-in renderer is not able to create a context.

Often this will occur while using iced_wgpu as the renderer without supported hardware (needs Vulkan, Metal or DX12). In this case, you could try using the iced_glow renderer:

First, check if it works with

$ cargo run --features iced/glow --package game_of_life

and then use it in your project with

iced = { version = "0.3", default-features = false, features = ["glow"] }

NOTE: Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0, but if you don't, right now there's no software fallback, so it means your hardware doesn't support Iced.

Contributing / Feedback

Contributions are greatly appreciated! If you want to contribute, please read our contributing guidelines for more details.

Feedback is also welcome! You can open an issue or, if you want to talk, come chat to our Discord server. Moreover, you can find me (and a bunch of awesome folks) over the #games-and-graphics and #gui-and-ui channels in the Rust Community Discord. I go by lone_scientist#9554 there.

Download Details: 
Author: iced-rs
Source Code: 
License: MIT
#rust #elm #programming 

iced: A cross-platform GUI library for Rust, inspired by Elm
Waylon  Bruen

Waylon Bruen


Webview: Tiny cross-platform webview library for C/C++/Golang


A tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs.

The goal of the project is to create a common HTML5 UI abstraction layer for the most widely used platforms.

It supports two-way JavaScript bindings (to call JavaScript from C/C++/Go and to call C/C++/Go from JavaScript).

It uses Cocoa/WebKit on macOS, gtk-webkit2 on Linux and Edge on Windows 10.

Webview for Go developers

If you are interested in writing Webview apps in C/C++, skip to the next section.

Getting started

Install Webview library with go get:

$ go get

Import the package and start using it:

package main

import ""

func main() {
    debug := true
    w := webview.New(debug)
    defer w.Destroy()
    w.SetTitle("Minimal webview example")
    w.SetSize(800, 600, webview.HintNone)

To build the app use the following commands:

# Linux
$ go build -o webview-example && ./webview-example

# MacOS uses app bundles for GUI apps
$ mkdir -p
$ go build -o
$ open # Or click on the app in Finder

# Windows requires special linker flags for GUI apps.
# It's also recommended to use TDM-GCC-64 compiler for CGo.
$ go build -ldflags="-H windowsgui" -o webview-example.exe

For more details see godoc.

Distributing webview apps

On Linux you get a standalone executable. It will depend on GTK3 and GtkWebkit2, so if you distribute your app in DEB or RPM format include those dependencies. An application icon can be specified by providing a .desktop file.

On MacOS you are likely to ship an app bundle. Make the following directory structure and just zip it:
└── Contents
    ├── Info.plist
    ├── MacOS
    |   └── example
    └── Resources
        └── example.icns

Here, Info.plist is a property list file and *.icns is a special icon format. You may convert PNG to icns online.

On Windows you probably would like to have a custom icon for your executable. It can be done by providing a resource file, compiling it and linking with it. Typically, windres utility is used to compile resources. Also, on Windows, webview.dll and WebView2Loader.dll must be placed into the same directory with your app executable.

Also, if you want to cross-compile your webview app - use xgo.

Known issues

Accessing localhost on Windows

If Edge (Chromium) isn't installed on the target machine webview will use a UWP application context which disallows loopback by default. To enable it you need to run the following command from a command prompt with admin priviledges:

CheckNetIsolation.exe LoopbackExempt -a -n="Microsoft.Win32WebViewHost_cw5n1h2txyewy"

For app distribution we recommend automating this in your installer.

Migrating from v0.1.1 to v0.10.0

  1. webview.Open() has been removed. Use other webview APIs to create a window, open a link and run main UI loop.
  2. webview.Debug() and webview.Debugf() have been removed. Use your favorite logging library to debug webview apps.
  3. webview.Settings struct has been removed. Title, URL and size are controlled via other API setters and can be updated at any time, not only when webview is created.
  4. Webview.Loop() has been removed. Use Run() instead.
  5. WebView.Run(), WebView.Terminate(), WebView.SetTitle(), WebView.Dispatch() stayed the same.
  6. WebView.Exit() has been renamed to WebView.Destroy()
  7. WebView.SetColor() and WebView.SetFullScreen() have been removed. Use Window() to get native window handle and probably write some Cgo code to adjust native window to your taste.
  8. webview.Dialog has been removed. But it is likely to be brought back as a standalone module.
  9. WebView.Eval() remained the same.
  10. WebView.InjectCSS() has been removed. Use eval to inject style tag with CSS inside.
  11. WebView.Bind() kept the name, but changed the semantics. Only functions can be bound. Not the structs, like in Lorca.

Webview for C/C++ developers

Download webview.h and include it in your C/C++ code:


#include "webview.h"
#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInt, HINSTANCE hPrevInst, LPSTR lpCmdLine,
                   int nCmdShow) {
int main() {
  webview::webview w(true, nullptr);
  w.set_title("Minimal example");
  w.set_size(480, 320, WEBVIEW_HINT_NONE);
  return 0;

Build it:

# Linux
$ c++ `pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0` -o webview-example
# MacOS
$ c++ -std=c++11 -framework WebKit -o webview-example
# Windows (x64)
$ c++ -mwindows -L./dll/x64 -lwebview -lWebView2Loader -o webview-example.exe


// main.c
#include "webview.h"
#include <stddef.h>

#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInt, HINSTANCE hPrevInst, LPSTR lpCmdLine,
                   int nCmdShow) {
int main() {
    webview_t w = webview_create(0, NULL);
    webview_set_title(w, "Webview Example");
    webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);
    webview_navigate(w, "");
    return 0;

Define C++ flags for the platform:

# Linux
$ CPPFLAGS="`pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0` -lstdc++"
# MacOS
$ CPPFLAGS="-std=c++11 -framework WebKit"
# Windows (x64)
$ CPPFLAGS="-mwindows -L./dll/x64 -lwebview -lWebView2Loader"

Build it:

$ g++ -c $CPPFLAGS -o webview.o  # build webview
$ gcc -c main.c -o main.o  # build C program
$ g++ main.o webview.o $CPPFLAGS -o webview-example  # link them together

For a complete C example see:

On Windows it is possible to use webview library directly when compiling with cl.exe, but WebView2Loader.dll is still required. To use MinGW you may dynamically link prebuilt webview.dll (this approach is used in Cgo bindings).

Full C/C++ API is described at the top of the webview.h file.

Migrating from v0.1.1 to v0.10.0

  1. Use opaque webview_t type instead of struct webview. Size, title and URL are controlled via API setter functions. Invoke callback has been replaced with webview_bind() and webview_return() to make native function bindings inter-operate with JS.
  2. If you have been using simplified webview() API to only open a single URL in a webview window - this function has been removed. You now have to create a new webview instance, configure and run it explicitly.
  3. webview_init() is replaced by webview_create() which creates a new webview instance.
  4. webview_exit() has been replaced with more meaningful webview_destroy().
  5. Main UI loop with webview_loop() inside has been replaced with webview_run() runs infinitely until the webview window is closed.
  6. webview_terminate() remains the same.
  7. webview_dispatch() remains the same.
  8. webview_set_title() remains the same.
  9. webview_set_color() has been removed. Use webview_get_window and native window APIs to control colors, transparency and other native window properties. At some point these APIs might be brought back.
  10. webview_set_fullscreen() has been removed, see above.
  11. webview_dialog() has been removed. But I'd like to see it added back as a separate independent module or library.
  12. webview_eval() remains the same.
  13. webview_inject_css() has been removed. Use webview_eval() to create style tag manually.
  14. webview_debug() has been removed. Use whatever fits best to your programming language and environment to debug your GUI apps.


  • A webview is not a full web browser and thus does not support alert, confirm and prompt dialogs. Additionally, console.* methods are not supported.
  • Ubuntu users need to install the webkit2gtk-4.0 as development dependency via sudo apt install webkit2gtk-4.0. If the package can't be found webkit2gtk-4.0-dev may be used instead.
  • FreeBSD is also supported via webkit2 which may be installed by running pkg install webkit2-gtk3.
  • Execution on OpenBSD requires wxallowed mount(8) option.
  • Calling Eval() or Dispatch() before Run() does not work, because the webview instance has only been configured, but not started yet.


This repository contains bindings for C, C++, and Go. Bindings for other languages are maintained separately.

Author: Webview
Source Code: 
License: MIT License

#go #golang #gui 

Webview: Tiny cross-platform webview library for C/C++/Golang
Waylon  Bruen

Waylon Bruen


Walk: A Windows GUI toolkit for The Go Programming Language

About Walk

Walk is a "Windows Application Library Kit" for the Go Programming Language.

Its primarily useful for Desktop GUI development, but there is some more stuff.


Make sure you have a working Go installation. See Getting Started


Walk currently requires Go 1.11.x or later.

To Install

Now run go get

Using Walk

The preferred way to create GUIs with Walk is to use its declarative sub package, as illustrated in this small example:


package main

import (
	. ""

func main() {
	var inTE, outTE *walk.TextEdit

		Title:   "SCREAMO",
		MinSize: Size{600, 400},
		Layout:  VBox{},
		Children: []Widget{
				Children: []Widget{
					TextEdit{AssignTo: &inTE},
					TextEdit{AssignTo: &outTE, ReadOnly: true},
				Text: "SCREAM",
				OnClicked: func() {

Create Manifest test.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
            <dpiAwareness xmlns="">PerMonitorV2, PerMonitor</dpiAwareness>
            <dpiAware xmlns="">True</dpiAware>

Then either compile the manifest using the rsrc tool, like this:

go get
rsrc -manifest test.manifest -o rsrc.syso

or rename the test.manifest file to test.exe.manifest and distribute it with the application instead.

Build app

In the directory containing test.go run

go build

To get rid of the cmd window, instead run

go build -ldflags="-H windowsgui"

Run app


Sample Output (Windows 7)

alt tag

More Examples

There are some examples that should get you started.

Application Manifest Files

Walk requires Common Controls 6. This means that you must put an appropriate application manifest file either next to your executable or embedded as a resource.

You can copy one of the application manifest files that come with the examples.

To embed a manifest file as a resource, you can use the rsrc tool.

IMPORTANT: If you don't embed a manifest as a resource, then you should not launch your executable before the manifest file is in place. If you do anyway, the program will not run properly. And worse, Windows will not recognize a manifest file, you later drop next to the executable. To fix this, rebuild your executable and only launch it with a manifest file in place.

CGo Optimizations

The usual default message loop includes calls to win32 API functions, which incurs a decent amount of runtime overhead coming from Go. As an alternative to this, you may compile Walk using an optional C implementation of the main message loop, by passing the walk_use_cgo build tag:

go build -tags walk_use_cgo

Author: lxn
Source Code: 
License: View license

#go #golang #windows #gui 

Walk: A Windows GUI toolkit for The Go Programming Language
Waylon  Bruen

Waylon Bruen


Ui: Platform-native GUI Library for Go

ui: platform-native GUI library for Go

This is a library that aims to provide simple GUI software development in Go. It is based on my libui, a simple cross-platform library that does the same thing, but written in C.

It runs on/requires:

  • Windows: cgo, Windows Vista SP2 with Platform Update and newer
  • Mac OS X: cgo, Mac OS X 10.8 and newer
  • other Unixes: cgo, GTK+ 3.10 and newer
    • Debian, Ubuntu, etc.: sudo apt-get install libgtk-3-dev
    • Red Hat/Fedora, etc.: sudo dnf install gtk3-devel

It also requires Go 1.8 or newer.

It currently aligns to libui's Alpha 4.1, with only a small handful of functions not available.


Package ui is currently mid-alpha software. Much of what is currently present runs stabily enough for the examples and perhaps some small programs to work, but the stability is still a work-in-progress, much of what is already there is not feature-complete, some of it will be buggy on certain platforms, and there's a lot of stuff missing. The libui README has more information.


Once you have the dependencies installed, a simple

go get

should suffice.


The in-code documentation is sufficient to get started, but needs improvement.

Some simple example programs are in the examples directory. You can go build each of them individually.

Windows manifests

Package ui requires a manifest that specifies Common Controls v6 to run on Windows. It should at least also state as supported Windows Vista and Windows 7, though to avoid surprises with other packages (or with Go itself; see this issue) you should state compatibility with higher versions of Windows too.

The simplest option is provided as a subpackage winmanifest; you can simply import it without a name, and it'll set things up properly:

import _ ""

You do not have to worry about importing this in non-Windows-only files; it does nothing on non-Windows platforms.

If you wish to use your own manifest instead, you can use the one in winmanifest as a template to see what's required and how. You'll need to specify the template in a .rc file and use windres in MinGW-w64 to generate a .syso file as follows:

windres -i resources.rc -o winmanifest_windows_GOARCH.syso -O coff

You may also be interested in the and packages, which provide other Go-like options for embedding the manifest.

Note that if you choose to ship a manifest as a separate .exe.manifest file instead of embedding it in your binary, and you use Cygwin or MSYS2 as the source of your MinGW-w64, Cygwin and MSYS2 instruct gcc to embed a default manifest of its own if none is specified. This default will override your manifest file! See this issue for more details, including workaround instructions.

macOS program execution

If you run a macOS program binary directly from the command line, it will start in the background. This is intentional; see this for more details.

Author: Andlabs
Source Code: 
License: View license

#go #golang #gui 

Ui: Platform-native GUI Library for Go
Waylon  Bruen

Waylon Bruen


Go-sciter: Go Bindings for Sciter

Go bindings for Sciter

Check this page for other language bindings (Delphi / D / Go / .NET / Python / Rust).


The ownership of project is transferred to this new organization. Thus the import path for golang should now be, but the package name is still sciter.


This package provides a Golang bindings of Sciter using cgo. Using go sciter you must have the platform specified sciter dynamic library downloaded from sciter-sdk, the library itself is rather small (under 5MB, less than 2MB when upxed) .

Most Sciter API are supported, including:

  • Html string/file loading
  • DOM manipulation/callback/event handling
  • DOM state/attribute handling
  • Custom resource loading
  • Sciter Behavior
  • Sciter Options
  • Sciter Value support
  • NativeFunctor (used in sciter scripting)

And the API are organized in more or less a gopher friendly way.

Things that are not supported:

  • Sciter Node API
  • TIScript Engine API

Getting Started

At the moment only Go 1.10 or higher is supported (issue #136).

Download the sciter-sdk

Extract the sciter runtime library from sciter-sdk to system PATH

The runtime libraries lives in bin bin.lnx bin.osx with suffix like dll so or dylib

  • Windows: simply copying bin\64\sciter.dll to c:\windows\system32 is just enough
  • Linux:
    • cd sciter-sdk/bin.lnx/x64
    • export LIBRARY_PATH=$PWD
    • echo $PWD >> libsciter.conf
    • sudo cp libsciter.conf /etc/
    • sudo ldconfig
    • ldconfig -p | grep sciter should print location
  • OSX:
    • cd sciter-sdk/bin.osx/

Set up GCC envrionmnet for CGO

mingw64-gcc (5.2.0 and 7.2.0 are tested) is recommended for Windows users.

Under Linux gcc(4.8 or above) and gtk+-3.0 are needed.

go get -x

Run the example and enjoy :)

Sciter Desktop UI Examples

Sciter Version Support

Currently supports Sciter version and higher.

About Sciter

Sciter is an Embeddable HTML/CSS/script engine for modern UI development, Web designers, and developers, can reuse their experience and expertise in creating modern looking desktop applications.

In my opinion, Sciter , though not open sourced, is an great desktop UI development envrionment using the full stack of web technologies, which is rather small (under 5MB) especially compared to CEF,Node Webkit and Atom Electron. :)

Finally, according to Andrew Fedoniouk the author and the Sciter END USER LICENSE AGREEMENT , the binary form of the Sciter dynamic libraries are totally free to use for commercial or non-commercial applications.

The Tailored Sciter C Headers

This binding ueses a tailored version of the sciter C Headers, which lives in directory: include. The included c headers are a modified version of the sciter-sdk standard headers.

It seems Sciter is developed using C++, and the included headers in the Sciter SDK are a mixture of C and C++, which is not quite suitable for an easy golang binding.

I'm not much fond of C++ since I started to use Golang, so I made this modification and hope Andrew Fedoniouk the author would provide pure C header files for Sciter. :)

Author: Sciter-sdk
Source Code: 

#go #golang #gui 

Go-sciter: Go Bindings for Sciter