Skip to content

Commit 2ec1144

Browse files
committed
I think it's ready :)
0 parents  commit 2ec1144

22 files changed

+907
-0
lines changed

.gitignore

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
.idea
2+
.idea/*
3+
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
*$py.class
8+
9+
# C extensions
10+
*.so
11+
12+
# Distribution / packaging
13+
.Python
14+
build/
15+
develop-eggs/
16+
dist/
17+
downloads/
18+
eggs/
19+
.eggs/
20+
lib/
21+
lib64/
22+
parts/
23+
sdist/
24+
var/
25+
wheels/
26+
pip-wheel-metadata/
27+
share/python-wheels/
28+
*.egg-info/
29+
.installed.cfg
30+
*.egg
31+
MANIFEST
32+
33+
# PyInstaller
34+
# Usually these files are written by a python script from a template
35+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
36+
*.manifest
37+
*.spec
38+
39+
# Installer logs
40+
pip-log.txt
41+
pip-delete-this-directory.txt
42+
43+
# Unit test / coverage reports
44+
htmlcov/
45+
.tox/
46+
.nox/
47+
.coverage
48+
.coverage.*
49+
.cache
50+
nosetests.xml
51+
coverage.xml
52+
*.cover
53+
*.py,cover
54+
.hypothesis/
55+
.pytest_cache/
56+
57+
# Translations
58+
*.mo
59+
*.pot
60+
61+
# Django stuff:
62+
*.log
63+
local_settings.py
64+
db.sqlite3
65+
db.sqlite3-journal
66+
67+
# Flask stuff:
68+
instance/
69+
.webassets-cache
70+
71+
# Scrapy stuff:
72+
.scrapy
73+
74+
# Sphinx documentation
75+
docs/_build/
76+
77+
# PyBuilder
78+
target/
79+
80+
# Jupyter Notebook
81+
.ipynb_checkpoints
82+
83+
# IPython
84+
profile_default/
85+
ipython_config.py
86+
87+
# pyenv
88+
.python-version
89+
90+
# pipenv
91+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
93+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
94+
# install all needed dependencies.
95+
#Pipfile.lock
96+
97+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
98+
__pypackages__/
99+
100+
# Celery stuff
101+
celerybeat-schedule
102+
celerybeat.pid
103+
104+
# SageMath parsed files
105+
*.sage.py
106+
107+
# Environments
108+
.env
109+
.venv
110+
env/
111+
venv/
112+
ENV/
113+
env.bak/
114+
venv.bak/
115+
116+
# Spyder project settings
117+
.spyderproject
118+
.spyproject
119+
120+
# Rope project settings
121+
.ropeproject
122+
123+
# mkdocs documentation
124+
/site
125+
126+
# mypy
127+
.mypy_cache/
128+
.dmypy.json
129+
dmypy.json
130+
131+
# Pyre type checker
132+
.pyre/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Dalya Gartzman
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# PyGraphicsGui
2+
3+
A "[CookieCutter](https://github.com/cookiecutter/cookiecutter)" for a Pythonic GUI with custom graphics -
4+
clone this to jump-start your project and learn how to integrate between [ModernGL](https://github.com/ModernGL/ModernGL)
5+
and [Tkinter](https://docs.python.org/3/library/Tkinter.html) on Python3.6.
6+
7+
![Wondering what happens when tou find Waldo? You will have to find Waldo yourself!](../master/data/WhereIsWaldoDemo.gif)
8+
9+
Wondering what happens when you find Waldo? You will have to find Waldo yourself!
10+
11+
*This project has been tested on Windows10, Ubuntu18.04 and macOS Mojave.*
12+
13+
14+
## Table of Contents
15+
16+
17+
* [Starting Your Own Project](#starting-your-own-project)
18+
19+
* [PyGraphicsGui Capabilities](#pygraphicsgui-capabilities)
20+
21+
* [About This Project - The Technical Side](#about-this-project---the-technical-side)
22+
23+
+ [The Main Folder](#the-main-folder)
24+
25+
+ [The Source Folder](#the-source-folder)
26+
27+
+ [The Graphic Engine Folder](#the-graphic-engine-folder)
28+
29+
* [About This Project - My Personal Story](#about-this-project---my-personal-story)
30+
31+
32+
33+
## Starting Your Own Project
34+
35+
1. If you are on Ubuntu, [install Tkinter](https://stackoverflow.com/a/45442774/2934048)
36+
(on [Windows10](https://stackoverflow.com/a/53912930/2934048) and
37+
[macOS](https://www.python.org/download/mac/tcltk/) Tkinter is bundled with Python):
38+
39+
sudo apt-get install python3.6-tk
40+
41+
1. Fork / Clone this repository
42+
43+
git clone https://github.com/DalyaG/PyGraphicsGui.git
44+
45+
1. Install requirements:
46+
47+
cd PyGraphicsGui
48+
49+
pip3 install -r requirements.txt
50+
51+
1. Test your PyGraphicsGui app!
52+
53+
python3 run_where_is_waldo.py
54+
55+
## PyGraphicsGui Capabilities
56+
57+
1. Click on the image with the left mouse button - if you didn't click on Waldo,
58+
you will see a red target and will be able to continue trying.
59+
60+
1. If you did click on Waldo - you will see a glorious exit message.
61+
62+
1. You can also press `esc` or the `x` on the top-right corner of the window (top-left on mac),
63+
If you wish to close the app.
64+
65+
1. At any point, you can resize the window and the targets of the failed detections will stay where they should.
66+
67+
68+
## About This Project - The Technical Side
69+
70+
This project was designed to be an as-lean-as-possible skeleton for a Pythonic desktop app with graphic capabilities.
71+
At the same time, it is meant to be easily expanded upon, without thinking to much on technicalities such as
72+
"where should I put this?" or "How do I write tests?" etc.
73+
74+
My goal going forward is for this project to include an introduction to ModernGL, computer graphics in general,
75+
Tkinter, and the Python behind-the-scenes that allow for this integration to work.
76+
77+
In the meanwhile, I hope the many links below will help you develop your new skills :)
78+
79+
The structure of this project is as follows:
80+
81+
### The Main Folder
82+
83+
* This README
84+
85+
* Requirements file for easy install (on Ubuntu you also need to install Tkinter)
86+
87+
* `run_where_is_waldo` - a lean runner file to run this app from terminal.
88+
89+
* License - My goal in this project is to make this knowledge accessible, so you can do pretty much what you like
90+
with the knowledge I gathered here.
91+
92+
If you publish something that is based on my work, be kind and link back to this project.
93+
94+
* `data` folder - contains the image to load and the location of Waldo (don't look!).
95+
96+
* `tests` folder - contains a base class that mocks the graphic engine, so that you could easily add tests to your app,
97+
and also an example tests file that validates some mathematical calculations.
98+
99+
### The Source Folder
100+
101+
As can be expected, the `src` folder is where the code is...
102+
103+
* `logging utils` holds a lean logger that helps with debugging, you can read more about it
104+
[here](https://codeburst.io/copy-pastable-logging-scheme-for-python-c17efcf9e6dc).
105+
106+
* `bounding box` is a lean dataclass that handles the location of Waldo
107+
108+
* `window_manager.py` is the main entry point - the class `WindowManager` creates and destroys the app,
109+
handles user events, draws elements on screen, and communicates with the graphic engine.
110+
111+
To learn more about Tkinter you can browse [this](http://effbot.org/zone/tkinter-index.htm) website,
112+
and I highly recommend the [sentdex Youtube channel](https://www.youtube.com/user/sentdex) -
113+
most of what I know about Tkinter is from
114+
[this](https://www.youtube.com/watch?v=HjNHATw6XgY&list=PLQVvvaa0QuDclKx-QpC9wntnURXVJqLyk) tutorial.
115+
116+
### The Graphic Engine Folder
117+
118+
I chose to put this in a separate folder (called `graphic_engine`, inside `src`) since once you start expanding on
119+
this project, and adding capabilities to your graphic engine, it helps to keep all the relevant logic in one place.
120+
121+
For now this folder contains:
122+
123+
* `graphic_engine` holds the main entry point to all the graphic capabilities, which is now pretty lean.
124+
The API is made up of mathematical conversion methods between the different coordinate systems. I included a
125+
glossary at the docstring of this class which I hope will take you the first steps in understanding this.
126+
127+
I somehow managed to avoid the term "viewport" in my graphic engine implementation, but it's a useful one
128+
to know, as it appears *everywhere* in computer graphics. Learn more about viewport
129+
[here](https://www.youtube.com/watch?v=DnEIdu8MpjY&list=PLE67F-VQUgLgws92d9gmP-AhBN_KQRGDW&index=18).
130+
131+
* `graphic_engine_initializer` is a helper that loads all the major graphics components, to avoid clutter in the
132+
main graphic engine class. I plan to expand on this topic in the future, as this initializer holds the key to
133+
understanding the basics of computer graphics, but for now we will settle for some external recommendations:
134+
135+
* The first 3 minutes of
136+
[this](https://www.youtube.com/watch?v=WMiggUPst-Q&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=2)
137+
video about vertex arrays (VAOs) and vertex buffers (VBOs) sorted out so many things in my head.
138+
139+
* The first half of [this](https://www.youtube.com/watch?v=21UsMuFTN0k) video helped me understand a bit
140+
about framebuffers.
141+
142+
* I learned a lot about graphics from
143+
[this tutorial series](https://www.youtube.com/watch?v=dwt2NAd1ZYY&list=PL4neAtv21WOlqpDzGqbGM_WN2hc5ZaVv7)
144+
about [OpenFrameworks](https://openframeworks.cc/).
145+
If you have some basic C++ knowledge I recommend you check it out.
146+
147+
* [This](https://www.youtube.com/watch?v=-tonZsbHty8)
148+
is an excellent visual explanation about the model-view-projection matrix.
149+
150+
And if you want to catch up on some linear algebra, it's always good (and fun!!) to watch some
151+
3Blue1Brown videos, such as [this](https://www.youtube.com/watch?v=kYB8IZa5AuE).
152+
153+
* [This](https://www.youtube.com/watch?v=vQ60rFwh2ig) is an excellent explanation about
154+
[homogeneous coordinates](https://en.wikipedia.org/wiki/Homogeneous_coordinates).
155+
156+
* `tkinter_framebuffer` is the "mediator" between the graphic engine and what is eventually presented on screen.
157+
This implementation takes the rendered graphics and "projects" it onto an "image" that Tkinter recognizes.
158+
Tkinter "thinks" it's presenting an image when in fact it is presenting a projection of the graphics rendered
159+
behind the scenes.
160+
161+
To understand how this object is initialized, you can read about Python's `with` statement
162+
[here](https://effbot.org/zone/python-with-statement.htm).
163+
164+
Notice that this "image" has a constant size, and so this "mediator" needs to be re-initialized every time
165+
the window size changes.
166+
167+
*A Thank You Note*: This object is almost a copy-paste of
168+
[this framebuffer](https://github.com/moderngl/moderngl/blob/master/examples/tkinter_framebuffer.py)
169+
from the moderngl repository. Understanding
170+
[this](https://github.com/moderngl/moderngl/blob/master/examples/window_tkinter.py)
171+
example was a huge step for me.
172+
173+
* `shaders` folder - a shader is a program that sends commands to the graphics card. It's basically a set of
174+
rules to apply to each pixel or object.
175+
176+
Although I am using the simplest shaders in this implementation, the first half of
177+
[this](https://www.youtube.com/watch?v=C8FK9Xn1gUM&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=49)
178+
video really ties the room together.
179+
180+
If you want to go a bit deeper - I learned a lot about shaders from
181+
[this](https://www.udemy.com/share/102cOcAEEbeFZbRHsB/) course on Udemy. You can also find some free videos
182+
on [Youtube](https://www.youtube.com/watch?v=uwzEqeMd7uQ&list=PLFky-gauhF452rW98W4cyZ8_2fXBjfGOT).
183+
184+
## About This Project - My Personal Story
185+
186+
The first steps in computer graphics were the hardest I had to take. Not only is the math non-trivial,
187+
but also the available information online is not suitable for beginners - full of jargon and assumes advanced knowledge.
188+
189+
Add to that my vision to develop an interactive desktop app in Python,
190+
and you get a month full of blood, sweat, tears, and self doubt.
191+
192+
Once I was able to make my vision come to life, I knew I had to share my knowledge and make it accessible.
193+
194+
Since I made the first prototype, I am easily developing tools that help me in my job as a
195+
computer vision algorithms engineer. These tools assist me in making it as easy as possible for the human-in-the-loop
196+
to participate in the AI flow.
197+
198+
My goal in this project is to make the onboarding stage of computer graphics as easy as possible,
199+
so that anyone could develop cool apps for fun and for work.
200+
201+
Hope you find this useful!

data/WhereIsWaldoDemo.gif

2.77 MB
Loading

data/waldo_bounding_box.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"left": 735,
3+
"top": 50,
4+
"right": 770,
5+
"bottom": 80
6+
}

data/where_is_waldo.jpeg

309 KB
Loading

requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mock~=4.0.2
2+
moderngl==5.6.1
3+
numpy~=1.19.0
4+
Pillow~=7.1.2
5+
PyGLM==1.0.0

0 commit comments

Comments
 (0)