Package: remi
GUI library for your Python applicationsRemi is a GUI library for Python applications that gets rendered in web browsers. 
This allows you to access your interface locally and remotely.Proud to be sponsored byDo you need support?Reddit - (subreddit RemiGUI)There is also adrag n drop GUI Editor. Look at theEditorsubfolder to download your copy.A demostrative video from the great REVVEN labsGetting StartedFor astableversion:pip install remiFor the most updatedexperimentalversionDownloador check out Remi from git and installpython setup.py installor install directly using pippip install git+https://github.com/rawpython/remi.gitThen start the test script (download it from githubhttps://github.com/rawpython/remi/blob/master/examples/widgets_overview_app.py):python widgets_overview_app.pyRemiPlatform independent Python GUI library. In less than 100 Kbytes of source code, perfect for your diet.Remi enables developers to create platform independent GUI with Python. The entire GUI is rendered in your browser.No HTMLis required, Remi automatically translates your Python code into HTML. When your app starts, it starts a web server that will be accessible on your network.A basic application appears like this:importremi.guiasguifromremiimportstart,AppclassMyApp(App):def__init__(self,*args):super(MyApp,self).__init__(*args)defmain(self):container=gui.VBox(width=120,height=100)self.lbl=gui.Label('Hello world!')self.bt=gui.Button('Press me!')# setting the listener for the onclick event of the buttonself.bt.onclick.do(self.on_button_pressed)# appending a widget to another, the first argument is a string keycontainer.append(self.lbl)container.append(self.bt)# returning the root widgetreturncontainer# listener functiondefon_button_pressed(self,widget):self.lbl.set_text('Button pressed!')self.bt.set_text('Hi!')# starts the web serverstart(MyApp)In order to see the user interface, open your preferred browser and type "http://127.0.0.1:8081".
You can change the URL address by specific **kwargs atstartfunction call. This will be discussed later.Tested on Android, Linux, Windows.
Useful on Raspberry Pi for Python script development. It allows interacting with your Raspberry Pi remotely from your mobile device.FAQWhy another GUI lib?Kivy, PyQT, and PyGObject all require native code for the host operating system, which means installing or compiling large dependencies. Remi needs only a web browser to show your GUI.Do I need to know HTML?NO, It is not required, you have to code only in Python.Is it open source?For sure! Remi is released under the Apache License. See theLICENSEfile for more details.Do I need some kind of web server?No, it's included.Brief tutorialImport Remi library and some other useful stuff.importremi.guiasguifromremiimportstart,AppSubclass theAppclass and declare amainfunction that will be the entry point of the application. Inside the main function you have toreturnthe root widget.classMyApp(App):def__init__(self,*args):super(MyApp,self).__init__(*args)defmain(self):lbl=gui.Label("Hello world!",width=100,height=30)# return of the root widgetreturnlblOutside the main class, start the application by calling the functionstartand passing the name of the class you declared previously as the parameter:# starts the webserverstart(MyApp)Run the script. If it's all OK the GUI will be opened automatically in your browser, otherwise, you have to type in the address bar "http://127.0.0.1:8081".You can customize optional parameters in thestartcall like:start(MyApp,address='127.0.0.1',port=8081,multiple_instance=False,enable_file_cache=True,update_interval=0.1,start_browser=True)Parameters:address: network interface IPport: listen portmultiple_instance: boolean, if True multiple clients that connect to your script has different App instances (identified by unique cookie session identifier)enable_file_cache: boolean, if True enable resource cachingupdate_interval: GUI update interval in seconds. If zero, the update happens at each change. If zero, the App.idle method is not called.start_browser: boolean that defines if the browser should be opened automatically at startupstandalone: boolean, indicates where to run the application as a standard Desktop application with its own window. If False, the interface is shown in a browser webpage.Additional Parameters:username: for a basic HTTP authenticationpassword: for a basic HTTP authenticationcertfile: SSL certificate filenamekeyfile: SSL key filessl_version: authentication version (i.e. ssl.PROTOCOL_TLSv1_2). If None disables SSL encryptionAll widgets constructors accept two standards**kwargs that are:width: can be expressed as int (and is interpreted as a pixel) or as str (and you can specify the measuring unit like '10%')height: can be expressed as int (and is interpreted as a pixel) or as str (and you can specify the measuring unit like '10%')Events and callbacksWidgets expose a set of events that happen during user interaction.
Such events are a convenient way to define the application behavior.
Each widget has its own callbacks, depending on the type of user interaction it allows.
The specific callbacks for the widgets will be illustrated later.In order to register a function as an event listener you have to call a function like eventname.do (i.e. onclick.do) passing as parameters the callback that will manage the event.
Follows an example:importremi.guiasguifromremiimportstart,AppclassMyApp(App):def__init__(self,*args):super(MyApp,self).__init__(*args)defmain(self):container=gui.VBox(width=120,height=100)self.lbl=gui.Label('Hello world!')self.bt=gui.Button('Press me!')# setting the listener for the onclick event of the buttonself.bt.onclick.do(self.on_button_pressed)# appending a widget to another, the first argument is a string keycontainer.append(self.lbl)container.append(self.bt)# returning the root widgetreturncontainer# listener functiondefon_button_pressed(self,widget):self.lbl.set_text('Button pressed!')self.bt.set_text('Hi!')# starts the web serverstart(MyApp)In the shown exampleself.bt.onclick.do(self.on_button_pressed)registers the self'son_button_pressedfunction as a listener for the eventonclickexposed by the Button widget.
Simple, easy.Listener's callbacks will receive the emitter's instance firstly, then all other parameters provided by the specific event.Besides the standard event registration (as aforementioned), it is possible to pass user parameters to listener functions. This can be achieves appending parameters to thedofunction call.importremi.guiasguifromremiimportstart,AppclassMyApp(App):def__init__(self,*args):super(MyApp,self).__init__(*args)defmain(self):container=gui.VBox(width=120,height=100)self.lbl=gui.Label('Hello world!')self.bt=gui.Button('Hello name!')self.bt2=gui.Button('Hello name surname!')# setting the listener for the onclick event of the buttonsself.bt.onclick.do(self.on_button_pressed,"Name")self.bt2.onclick.do(self.on_button_pressed,"Name","Surname")# appending a widget to anothercontainer.append(self.lbl)container.append(self.bt)container.append(self.bt2)# returning the root widgetreturncontainer# listener functiondefon_button_pressed(self,widget,name='',surname=''):self.lbl.set_text('Button pressed!')widget.set_text('Hello '+name+' '+surname)# starts the web serverstart(MyApp)This allows great flexibility, getting different behaviors with the same event listener definition.HTML Attribute accessibilitySometimes it is required to access Widget's HTML representation in order to manipulate HTML attributes.
The library allows accessing this information easily.A simple example: It is the case where you would like to add a hover text to a widget. This can be achieved by thetitleattribute of an HTML tag.
In order to do this:widget_instance.attributes['title']='Your title content'A special case of HTML attribute is thestyle.
The style attributes can be altered in this way:widget_instance.style['color']='red'The assignment of a new attribute automatically creates it.For a reference list of HTML attributes, you can refer tohttps://www.w3schools.com/tags/ref_attributes.aspFor a reference list of style attributes, you can refer tohttps://www.w3schools.com/cssref/default.aspTake care about internally used attributes. These are:class: It is used to store the Widget class name for styling purposeid: It is used to store the instance id of the widget for callback managementRemote accessIf you are using your REMI app remotely, with a DNS and behind a firewall, you can specify special parameters in thestartcall:port: HTTP server port. Don't forget to NAT this port on your router;start(MyApp,address='0.0.0.0',port=8081)Standalone ExecutionI suggest using the browser as a standard interface window.However, you can avoid using the browser.
This can be simply obtained joining REMI andPyWebView.
Here is an example about thisstandalone_app.py.Be aware that PyWebView uses qt, gtk and so on to create the window. An outdated version of these libraries can cause UI problems. If you experience UI issues, update these libraries, or better avoid standalone execution.AuthenticationIn order to limit remote access to your interface, you can define a username and password. It consists of a simple authentication process.
Just define the parametersusernameandpasswordin the start call:start(MyApp,username='myusername',password='mypassword')StylingIn order to define a new style for your app, you have to do the following.
Create aresfolder and pass it to your App class constructor:classMyApp(App):def__init__(self,*args):res_path=os.path.join(os.path.dirname(__file__),'res')super(MyApp,self).__init__(*args,static_file_path={'res':res_path})Copy the standard style.css file from the remi folder and paste it inside yourresfolder. Edit it in order to customize.
This way the standardstyle.cssfile gets overridden by the one you created.CompatibilityRemi is made to be compatible from Python2.7 to Python3.X. Please notify compatibility issues.SecurityRemi should be intended as a standard desktop GUI framework.
The library itself doesn't implement security strategies, and so it is advised to not expose its access to unsafe public networks.When loading data from external sources, consider protecting the application from potential javascript injection before displaying the content directly.Projects using RemiPySimpleGUI: Launched in 2018 Actively developed and supported. Supports tkinter, Qt, WxPython, Remi (in browser). Create custom layout GUI's simply. Python 2.7 & 3 Support. 100+ Demo programs & Cookbook for rapid start. Extensive documentation.App Template For REMI: A really well written template for multiview applications.Web based dynamic reconfigure for ROS robotsrazmqEspresso-ARMPiPresentsThe Python Banyan FrameworkLightShowPi show managerrElectrum: A powerful promising Electrum wallet manager for safe transactions.Other ImplementationsListed here are other implementations of this library:cremi: (WIP) developed for your C++ projects byClaudio CannatÃ.