Posted on: 2021-04-13
Let's eel (Vol.2 Callbacks)
5 minutes read.
Read Let's Eel (Basics) first.
What were those ()()
Callbacks in python:
first, make these files: (just like before)
Let's start with making an HTML file:
<!-- web/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript" src="eel.js"></script>
<title>Let's Eel Again</title>
</head>
<body>
<h1>Let's Eel Again</h1>
<h4>
if you look at python's terminal you will see some random number sent from
js and catch with callback functions in python
</h4>
<script src="app.js"></script>
</body>
</html>
and the style:
/* web/styles.css */
body {
background-color: #fdcfd7;
font-family: Arial, Helvetica, sans-serif;
}
.textInput {
color: #353535;
padding: 10px;
margin-right: 5px;
border-radius: 2px;
border: 0;
border-bottom: 2px solid #f875aa;
outline: none;
font-size: large;
transition-duration: 0.2s;
background-color: #ffe0e5;
}
.textInput:focus {
background-color: #ffe0e5;
border-bottom: 4px solid #f875aa;
padding-bottom: 8px;
transition-duration: 0.2s;
}
.buttonInput {
background-color: #f875aa;
color: #ffffff;
padding: 10px;
border-radius: 2px;
border: 2px solid #f875aa;
outline: none;
transition-duration: 1s;
font-size: large;
}
.buttonInput:hover,
.buttonInput:focus {
background-color: #ff3184;
padding: 10px;
border-radius: 2px;
border: 2px solid #ff3184;
outline: none;
transition-duration: 1s;
cursor: pointer;
}
.formJsToPy {
padding-top: 20px;
padding-bottom: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.center {
padding-top: 20px;
padding-bottom: 20px;
justify-content: center;
align-items: center;
}
hr {
color: #303841;
padding: 0;
border: 3px solid #ff3184;
border-top: 0;
}
h4,
h5,
p {
color: #303841;
text-align: center;
padding-bottom: 0;
margin-bottom: 0;
}
h1 {
padding-top: 50px;
text-align: center;
}
now the Javascript:
this will generate a random number between 0 and 1 and returns it.
// web/app.js
eel.expose(js_random);
function js_random() {
return Math.random();
}
on the Python side, if you try to get the returned value of the eel.js_random()()
, and print it Before the eel.start('index.html')
first, it will take some time to load(unusual) and then it will prints None
.😑
# letsEel.py
import eel
eel.init('.//web')
randomNumberFromJs = eel.js_random()()
print(randomNumberFromJs)# will print None
eel.start('index.html')
# This is Wrong
So as I said here, you would either use block=False
and get the after that line, or you can use Callback functions!
These two links article explained callback functions completely(callbacks and w3 Callbacks)
We use callbacks in python like this:
# letsEel.py
import eel
eel.init('.//web')
eel.js_random()(lambda n: print(n))# callback using lambda
def printRandom(n):
print(n)
eel.js_random()(printRandom)# callback using the name of a funcction
eel.start('index.html')
in the second parenthesis, you can write lambda like this eel.js_random()(lambda n: print(n))
. n
will replace with the returned value from js, and then will be printed.
Or you can write another function and pass its name to the second parenthesis.
as you see, you don't need to add block=False
any more.🥳
If you run this the result will be:
Using callbacks is more efficient.
Let's use callbacks on Javascript:
Html file:
<!-- web/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript" src="eel.js"></script>
<title>Let's Eel Again</title>
</head>
<body>
<h1>Let's Eel Again</h1>
<h4>
if you look at python's terminal you will see some random number sent from
js and catch with callback functions in python
</h4>
<hr />
<h4>
These random numbers are form python and shown by three kinds of callback
functions
</h4>
<div class="center">
<p id="showRandom1"></p>
<p id="showRandom2"></p>
<p id="showRandom3"></p>
</div>
<script src="app.js"></script>
</body>
</html>
Python file:
# letsEel.py
import eel
eel.init('.//web')
eel.js_random()(lambda n: print(n))# callback using lambda
def printRandom(n):
print(n)
eel.js_random()(printRandom)# callback using the name of a funcction
@ eel.expose
def py_random():
return random.randint(0, 100)
eel.start('index.html')
and the Wrong Javascript file:
// web/app.js
eel.expose(js_random);
function js_random() {
return Math.random();
}
let num = eel.py_random()(); //[object Promise]
document.getElementById("showRandom1").innerText = num;
// Wrong way
if you run the file you will get [object Promise]
on num
that shows on HTML!
you can use the async function too like here, but it's better to use callback functions.
in Javascript, I know three ways of callback functions:
// web/app.js
eel.expose(js_random);
function js_random() {
return Math.random();
}
//Callback 1
function updateTheHtml(n) {
document.getElementById("showRandom1").innerText = n;
}
eel.py_random()(updateTheHtml);// no need to use async here
//Callback 2
eel.py_random()(function (n) {
document.getElementById("showRandom3").innerText = n;
});
//Callback 3 (Array function)
eel.py_random()((n) => (document.getElementById("showRandom2").innerText = n));
// Not work
// let num = eel.py_random()(); //[object Promise]
// document.getElementById("showRandom1").innerText = num;
and if you run the file you will get something like this:
The whole code is here
Facing some errors?! go here
Let's make executable
Making a single executable file is so easy, I use pyinstaller to do that. So first install it using pip install pyinstaller
.
Then cd
to the project folder and run this command:
python -m eel letsCode.py "web" --onefile --noconsole
letsCode.py
is the name of the main python file.
web
is the name of the webpage folder.
after quite a long time a single execution file will be generated on a folder called dist
.
HAVE PROBLEM? Leave a comment.
Some projects made with eel
1. Sudoku solver:
Thanks to Lior Sinai for his great sudoku solver. Head over to his website to see the solver algorithm and his Github repository to see the code for both solver and UI.
2. Minesweeper:
Thanks to Raemond Bergstrom-Wood for his great minesweeper code. You can find both GUI and TUI versions in his repository. (I made the GUI 😎 )
Here are some other themes:
3. Crack the code:
It's a logical game that you should guess the code. here is the code.
As it seems I could've easily made this without python😅. [I also made the version without python ver and it's available here]