# easy_gui
easy_gui is a high-level Python library designed to simplify the process of creating GUI applications by wrapping tkinter. Solving problems is tricky enough... using our solutions should be EASY!
# Features
- Quickly and easily build a GUI by subclassing easy_gui.EasyGUI
- Add easy_gui Widget objects (check out widgets.py for details on each):
- Button, CanvasButton, Label, Entry, LabelEntry, CheckBox, DropDown, ListBox, Table, Tree, Slider, MatplotlibPlot, Canvas, ProgressBar, ScrolledText, StdOutBox, DatePicker
- Create one or more Sections (including nested Sections) to help organize GUI elements
- CSS Grid-style layouts
- Simply create a popup window using EasyGUI.popup()
- Simply create popup tooltips for widgets using Widget.add_tooltip()
- Multithreading for GUI responsiveness (set "separate_thread=True" when creating a Button Widget)
- Easy to install with few dependancies - just matplotlib (but you want to make plots anyway, right?!)
# Quickstart
- Installing easy_gui is easy enough. Simply use pip:
```
pip install easy_gui
```
- To create an application with easy_gui, subclass the easy_gui.EasyGUI class and add elements in the init method.
- Here is the most simple example:
```
import easy_gui
class GUI(easy_gui.EasyGUI):
def __init__(self):
self.add_widget(type='label', text='Example Label')
self.add_widget(type='button', text='Button', command_func=lambda x: print('TEST'))
application = GUI()
```
<img src="examples/super_simple_gui.png" width="200px">
- Now for a more substantial example that also shows CSS-style layout capabilities. See the script examples/simple_gui.py for this code with additional explanatory comments:
```
import easy_gui
class GUI(easy_gui.EasyGUI):
def __init__(self):
self.title('Animal Diet Generator')
self.geometry("425x170")
section = self.add_section('example_section')
section.configure_grid(['title title output',
'label1 entry1 output',
'label2 entry2 output',
'run_button run_button output'])
section.add_widget(type='label', text='Animal Diet Generator!', grid_area='title')
section.add_widget(type='label', text='Animal:', grid_area='label1')
self.animal = section.add_widget(type='entry', grid_area='entry1')
section.add_widget(type='label', text='Food:', grid_area='label2')
self.food = section.add_widget(type='entry', grid_area='entry2')
section.add_widget(type='stdout', grid_area='output')
section.add_widget(type='button', text='Generate Diet!', grid_area='run_button', command_func=self.diet)
def diet(self, event):
print(f'The {self.animal.get()} likes to eat {self.food.get()}!')
application = GUI()
```
<img src="examples/simple_gui.png" width="425px">
# More Firepower
The toy examples above show the basics for getting started. Below is a more robust example for what a simple tool could look like.
This example highlights a number of powerful features such as:
- CSS-style grid layouts (literally make a picture of what you want to see with a list of strings)
- Flexible, high-level Widgets that are quick to add or manipulate
- Quick and easy popup window using `with self.popup() as popup:`
<img src="examples/moderate_gui.png" width="800px">
```
import easy_gui
import random
from matplotlib.figure import Figure
class GUI(easy_gui.EasyGUI):
def __init__(self):
self.title('Data Generator')
self.geometry("800x550")
self.configure_grid(['check data_gen info',
'tree tree data',
'tree tree plot'])
self.parabolic = self.add_widget('checkbox', 'Parabolic Data', grid_area='check')
self.add_widget('btn', 'Generate New Data', grid_area='data_gen', use_ttk=True, command_func=self.generate_data)
self.add_key_trigger('new', self.generate_data)
print('Also can generate new data by simply typing "new"!')
info = self.add_section(grid_area='info')
info.configure_grid([' . title . ',
'mean min max'])
info.add_widget('lbl', 'Data Information', underline=True, bold=True, grid_area='title')
self.mean = info.add_widget('lbl', 'Mean:', grid_area='mean')
self.min = info.add_widget('lbl', 'Minimum:', grid_area='min')
self.max = info.add_widget('lbl', 'Maximum:', grid_area='max')
self.tree = self.add_widget('tree', grid_area='tree', height=10)
self.tree.bind_select(self.refresh_display)
self.table = self.add_widget('table', rows=2, columns=11, border=True, grid_area='data')
self.table[1, 1] = 'X Values'
self.table[2, 1] = 'Y Values'
self.plot = self.add_widget('matplotlib', grid_area='plot')
self.add_menu(commands={}, cascades={'Data': {'Save Data to CSV': self.save_data}})
self.data_sets = [] # store all generated datasets in this list
self.generate_data() # start with one initial dataset
def current_data(self):
name, x_vals, y_vals = [tup for tup in self.data_sets if tup[0] == self.tree.current_row['text']][0]
return name, x_vals, y_vals
def refresh_tree(self, *args):
self.tree.clear()
for name, x_vals, y_vals in self.data_sets:
self.tree.insert_row(name)
self.tree.select_first_row()
self.refresh_display()
def refresh_display(self, *args):
name, x_vals, y_vals = self.current_data()
# Update summary info at top
self.mean.set(f'Mean: {round(sum(y_vals) / len(y_vals), 1)}')
self.min.set(f'Minimum: {min(y_vals)}')
self.max.set(f'Maximum: {max(y_vals)}')
# Update table with current data
for index, (x, y) in enumerate(zip(x_vals, y_vals)):
self.table[1, index+2] = x
self.table[2, index+2] = y
# Update the plot
fig = Figure(figsize=(5, 3), dpi=100)
ax = fig.add_subplot(111)
ax.set_title('Plot of X and Y Values')
ax.scatter(x_vals, y_vals)
self.plot.draw_plot(mpl_figure=fig)
def generate_data(self, *args):
x_vals = list(range(1, 11))
if not self.parabolic.get():
y_vals = [round(x + random.random() * 2, 1) for x in x_vals]
else:
y_vals = [round((x - 5 + random.random()) ** 2, 1) for x in x_vals]
self.data_sets.append((f'Dataset {len(self.data_sets)+1}' + (' (Parabolic)' if self.parabolic.get() else ''), x_vals, y_vals))
self.refresh_tree()
with self.popup() as popup:
popup.geometry('200x80')
popup.add_widget('lbl', 'New data generated!', bold=True)
def save_data(self, *args):
with open('Moderate GUI Data.csv', 'w') as f:
f.write('Dataset,X_Values,Y_Values\n')
for name, x_vals, y_vals in self.data_sets:
for x, y in zip(x_vals, y_vals):
f.write(f'{name},{x},{y}\n')
print('Data saved to CSV file!')
if __name__ == '__main__':
GUI()
```
License
----
MIT
Raw data
{
"_id": null,
"home_page": "https://github.com/zachbateman/easy_gui.git",
"name": "easy-gui",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "GUI,TKINTER,APPLICATION,SIMPLE,EASY",
"author": "Zach Bateman",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/2c/fd/77097fbcaa91b861e2edc9172175d52aa12bca5191559a213727ad8a03f4/easy_gui-0.4.10.tar.gz",
"platform": null,
"description": "# easy_gui\r\n\r\neasy_gui is a high-level Python library designed to simplify the process of creating GUI applications by wrapping tkinter. Solving problems is tricky enough... using our solutions should be EASY!\r\n\r\n\r\n# Features\r\n\r\n - Quickly and easily build a GUI by subclassing easy_gui.EasyGUI\r\n - Add easy_gui Widget objects (check out widgets.py for details on each):\r\n - Button, CanvasButton, Label, Entry, LabelEntry, CheckBox, DropDown, ListBox, Table, Tree, Slider, MatplotlibPlot, Canvas, ProgressBar, ScrolledText, StdOutBox, DatePicker\r\n - Create one or more Sections (including nested Sections) to help organize GUI elements\r\n - CSS Grid-style layouts\r\n - Simply create a popup window using EasyGUI.popup()\r\n - Simply create popup tooltips for widgets using Widget.add_tooltip()\r\n - Multithreading for GUI responsiveness (set \"separate_thread=True\" when creating a Button Widget)\r\n - Easy to install with few dependancies - just matplotlib (but you want to make plots anyway, right?!)\r\n\r\n\r\n# Quickstart\r\n\r\n - Installing easy_gui is easy enough. Simply use pip:\r\n ```\r\n pip install easy_gui\r\n ```\r\n\r\n - To create an application with easy_gui, subclass the easy_gui.EasyGUI class and add elements in the init method.\r\n\r\n - Here is the most simple example:\r\n ```\r\n import easy_gui\r\n\r\n class GUI(easy_gui.EasyGUI):\r\n def __init__(self):\r\n self.add_widget(type='label', text='Example Label')\r\n self.add_widget(type='button', text='Button', command_func=lambda x: print('TEST'))\r\n\r\n application = GUI()\r\n ```\r\n <img src=\"examples/super_simple_gui.png\" width=\"200px\">\r\n\r\n\r\n - Now for a more substantial example that also shows CSS-style layout capabilities. See the script examples/simple_gui.py for this code with additional explanatory comments:\r\n ```\r\n import easy_gui\r\n\r\n class GUI(easy_gui.EasyGUI):\r\n def __init__(self):\r\n self.title('Animal Diet Generator')\r\n self.geometry(\"425x170\")\r\n\r\n section = self.add_section('example_section')\r\n section.configure_grid(['title title output',\r\n 'label1 entry1 output',\r\n 'label2 entry2 output',\r\n 'run_button run_button output'])\r\n section.add_widget(type='label', text='Animal Diet Generator!', grid_area='title')\r\n section.add_widget(type='label', text='Animal:', grid_area='label1')\r\n self.animal = section.add_widget(type='entry', grid_area='entry1')\r\n section.add_widget(type='label', text='Food:', grid_area='label2')\r\n self.food = section.add_widget(type='entry', grid_area='entry2')\r\n section.add_widget(type='stdout', grid_area='output')\r\n section.add_widget(type='button', text='Generate Diet!', grid_area='run_button', command_func=self.diet)\r\n\r\n def diet(self, event):\r\n print(f'The {self.animal.get()} likes to eat {self.food.get()}!')\r\n\r\n application = GUI()\r\n ```\r\n <img src=\"examples/simple_gui.png\" width=\"425px\">\r\n\r\n\r\n# More Firepower\r\n\r\nThe toy examples above show the basics for getting started. Below is a more robust example for what a simple tool could look like.\r\nThis example highlights a number of powerful features such as:\r\n - CSS-style grid layouts (literally make a picture of what you want to see with a list of strings)\r\n - Flexible, high-level Widgets that are quick to add or manipulate\r\n - Quick and easy popup window using `with self.popup() as popup:`\r\n\r\n <img src=\"examples/moderate_gui.png\" width=\"800px\">\r\n\r\n ```\r\nimport easy_gui\r\nimport random\r\nfrom matplotlib.figure import Figure\r\n\r\n\r\nclass GUI(easy_gui.EasyGUI):\r\n def __init__(self):\r\n self.title('Data Generator')\r\n self.geometry(\"800x550\")\r\n\r\n self.configure_grid(['check data_gen info',\r\n 'tree tree data',\r\n 'tree tree plot'])\r\n\r\n self.parabolic = self.add_widget('checkbox', 'Parabolic Data', grid_area='check')\r\n self.add_widget('btn', 'Generate New Data', grid_area='data_gen', use_ttk=True, command_func=self.generate_data)\r\n self.add_key_trigger('new', self.generate_data)\r\n print('Also can generate new data by simply typing \"new\"!')\r\n\r\n info = self.add_section(grid_area='info')\r\n info.configure_grid([' . title . ',\r\n 'mean min max'])\r\n info.add_widget('lbl', 'Data Information', underline=True, bold=True, grid_area='title')\r\n self.mean = info.add_widget('lbl', 'Mean:', grid_area='mean')\r\n self.min = info.add_widget('lbl', 'Minimum:', grid_area='min')\r\n self.max = info.add_widget('lbl', 'Maximum:', grid_area='max')\r\n\r\n self.tree = self.add_widget('tree', grid_area='tree', height=10)\r\n self.tree.bind_select(self.refresh_display)\r\n\r\n self.table = self.add_widget('table', rows=2, columns=11, border=True, grid_area='data')\r\n self.table[1, 1] = 'X Values'\r\n self.table[2, 1] = 'Y Values'\r\n\r\n self.plot = self.add_widget('matplotlib', grid_area='plot')\r\n\r\n self.add_menu(commands={}, cascades={'Data': {'Save Data to CSV': self.save_data}})\r\n\r\n self.data_sets = [] # store all generated datasets in this list\r\n self.generate_data() # start with one initial dataset\r\n\r\n\r\n def current_data(self):\r\n name, x_vals, y_vals = [tup for tup in self.data_sets if tup[0] == self.tree.current_row['text']][0]\r\n return name, x_vals, y_vals\r\n\r\n def refresh_tree(self, *args):\r\n self.tree.clear()\r\n for name, x_vals, y_vals in self.data_sets:\r\n self.tree.insert_row(name)\r\n self.tree.select_first_row()\r\n self.refresh_display()\r\n\r\n def refresh_display(self, *args):\r\n name, x_vals, y_vals = self.current_data()\r\n\r\n # Update summary info at top\r\n self.mean.set(f'Mean: {round(sum(y_vals) / len(y_vals), 1)}')\r\n self.min.set(f'Minimum: {min(y_vals)}')\r\n self.max.set(f'Maximum: {max(y_vals)}')\r\n\r\n # Update table with current data\r\n for index, (x, y) in enumerate(zip(x_vals, y_vals)):\r\n self.table[1, index+2] = x\r\n self.table[2, index+2] = y\r\n\r\n # Update the plot\r\n fig = Figure(figsize=(5, 3), dpi=100)\r\n ax = fig.add_subplot(111)\r\n ax.set_title('Plot of X and Y Values')\r\n ax.scatter(x_vals, y_vals)\r\n self.plot.draw_plot(mpl_figure=fig)\r\n\r\n def generate_data(self, *args):\r\n x_vals = list(range(1, 11))\r\n if not self.parabolic.get():\r\n y_vals = [round(x + random.random() * 2, 1) for x in x_vals]\r\n else:\r\n y_vals = [round((x - 5 + random.random()) ** 2, 1) for x in x_vals]\r\n self.data_sets.append((f'Dataset {len(self.data_sets)+1}' + (' (Parabolic)' if self.parabolic.get() else ''), x_vals, y_vals))\r\n self.refresh_tree()\r\n\r\n with self.popup() as popup:\r\n popup.geometry('200x80')\r\n popup.add_widget('lbl', 'New data generated!', bold=True)\r\n\r\n def save_data(self, *args):\r\n with open('Moderate GUI Data.csv', 'w') as f:\r\n f.write('Dataset,X_Values,Y_Values\\n')\r\n for name, x_vals, y_vals in self.data_sets:\r\n for x, y in zip(x_vals, y_vals):\r\n f.write(f'{name},{x},{y}\\n')\r\n print('Data saved to CSV file!')\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n GUI()\r\n ```\r\n\r\n\r\n\r\nLicense\r\n----\r\nMIT\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Easy Python GUI applications (tkinter wrapper)",
"version": "0.4.10",
"split_keywords": [
"gui",
"tkinter",
"application",
"simple",
"easy"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5e0d68c33cf814dbe202bcff6b5cb5db5048e6340df844dad90e1cda888f0245",
"md5": "62f98250e590e77ac2b3bb8ff651ac9d",
"sha256": "1fd449ddf3dda8a87fa1c6fcc68ac22fa11387499f125faa406050797b977f0a"
},
"downloads": -1,
"filename": "easy_gui-0.4.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "62f98250e590e77ac2b3bb8ff651ac9d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 24624,
"upload_time": "2023-03-22T00:59:36",
"upload_time_iso_8601": "2023-03-22T00:59:36.975572Z",
"url": "https://files.pythonhosted.org/packages/5e/0d/68c33cf814dbe202bcff6b5cb5db5048e6340df844dad90e1cda888f0245/easy_gui-0.4.10-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2cfd77097fbcaa91b861e2edc9172175d52aa12bca5191559a213727ad8a03f4",
"md5": "f39f6fc4e9559d28ed859bc753fbd680",
"sha256": "f49d82d6e1ceb9350abfa87a58c83cd808525eca9d7bc7b22661ee0ba6d7bf73"
},
"downloads": -1,
"filename": "easy_gui-0.4.10.tar.gz",
"has_sig": false,
"md5_digest": "f39f6fc4e9559d28ed859bc753fbd680",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 25500,
"upload_time": "2023-03-22T00:59:38",
"upload_time_iso_8601": "2023-03-22T00:59:38.999521Z",
"url": "https://files.pythonhosted.org/packages/2c/fd/77097fbcaa91b861e2edc9172175d52aa12bca5191559a213727ad8a03f4/easy_gui-0.4.10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-22 00:59:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "zachbateman",
"github_project": "easy_gui.git",
"lcname": "easy-gui"
}