Question

Python has a lot of GUI libraries: tkinter, wxWidgets, pyGTK etc. But all these GUIs need to be installed and quite heavyweight, so it's a bit complex to deploy end-user GUI python apps that relay on mentioned GUI libraries.

Recently, I have thought about python's built-in ctypes module. Theoretically, it's possible to create a pure python GUI library that will use ctypes on windows ( windll.user32.CreateWindowEx, etc ), native pyObjC on MacOS and pyGTK / pyQt on gnome / kde. Does such a library exist? If not, what do you think is wrong with this idea?

Was it helpful?

Solution

The path of least effort and best results would be to learn what it takes to deploy an app using those existing GUI libraries.

OTHER TIPS

starting in Python 2.7 and 3.1, Tk will look a lot better.

http://docs.python.org/dev/whatsnew/2.7.html#ttk-themed-widgets-for-tk

"Tcl/Tk 8.5 includes a set of themed widgets that re-implement basic Tk widgets but have a more customizable appearance and can therefore more closely resemble the native platform’s widgets. This widget set was originally called Tile, but was renamed to Ttk (for “themed Tk”) on being added to Tcl/Tck release 8.5."

Tkinter is part of the python standard distribution and is installed by default. Expect to find this on all python installs where there is a graphical display in the first place.

Notion of "pure python gui library" is wrong because ultimately you will be using system level calls and widgets, may be thru ctypes but that doesn't change the fact that if you start implementing your idea you will eventually become wxPython

Principally what's wrong is that it's reinventing wheels that have already been done by the makers of GTK, Tk, Wx, QT and their ilk. While a pure python GUI is technically feasible, and projects such as anygui did attempt something similar, there is relatively little to gain by doing this.

The native toolkits will also do a better job of covering the differences between the underlying platforms (native dialogs etc.). This means that the toolkits allow you to write a portable application that needs little if any platform specific code - most of this is abstracted by the underlying toolkit.

Distribution mechanisms such as py2exe on windows and any of the linux methods allow you to bundle DLLs with the application, so you can make an installer that drops any native components it needs into place. However, there isn't really a generic cross-platform way to do this so you will need to maintain separate installers for each platform.

For one thing, all those libraries use different abstractions, so anything that worked with all of them is likely to wind up supporting a least-common-denominator set of functionality, or doing a LOT of work to use each to its fullest.

Not really sure what you mean by "heavyweight."

wx uses native controls on each platform, and is about as easy to use in Python as I can imagine; after all, GUI APIs are complex because GUIs can get complex.

I think wx, for the effort required to build a window and the quality of what shows up on screen, is great. I don't think you're likely to roll something better on your own.

I think it's about not inventig the wheel. It would work, but why should you do that? All the GUI libraries you mentioned are stable and more or less bullet proofen.

I could imagine that there are some experiments implementing a pure python library. But I never saw one. Everything about GUIs is hard work and a pure python library wouldn't have such a big audience.

How about a lightweight wrapper around tkinter so that it doesn't require a lot of setup? PySimpleGUI is built on top of tkinter which means it runs everywhere tkinter runs.

The advantage over using it versus tkinter is the amount of code that is required. The PySimpleGUI programs tend to be really compact.

Here is an example showing a custom layout using many of the available widgets.

enter image description here

The code to generate it is at the end. It may look like a lot of code, but that's it. It would take pages and pages and pages of tkinter code to do the same thing.

import PySimpleGUI as sg

sg.ChangeLookAndFeel('GreenTan')
# ------ Menu Definition ------ #
menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
            ['&Edit', ['Paste', ['Special', 'Normal', ], 'Undo'], ],
            ['&Help', '&About...'], ]
# ------ Column Definition ------ #
column1 = [[sg.Text('Column 1', background_color='lightblue', justification='center', size=(10, 1))],
           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],
           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')],
           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]]

layout = [
    [sg.Menu(menu_def, tearoff=True)],
    [sg.Text('(Almost) All widgets in one Window!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
    [sg.Text('Here is some text.... and a place to enter text')],
    [sg.InputText('This is my text')],
    [sg.Frame(layout=[
    [sg.Checkbox('Checkbox', size=(10,1)),  sg.Checkbox('My second checkbox!', default=True)],
    [sg.Radio('My first Radio!     ', "RADIO1", default=True, size=(10,1)), sg.Radio('My second Radio!', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags')],
    [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)),
     sg.Multiline(default_text='A second multi-line', size=(35, 3))],
    [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)),
     sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)],
    [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))],
    [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),
     sg.Frame('Labelled Group',[[
     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25),
     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75),
     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10),
     sg.Column(column1, background_color='lightblue')]])],
    [sg.Text('_' * 80)],
    [sg.Text('Choose A Folder', size=(35, 1))],
    [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
     sg.InputText('Default Folder'), sg.FolderBrowse()],
    [sg.Submit(tooltip='Click to submit this form'), sg.Cancel()]]

window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout)
button, values = window.Read()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top