Getting Started with PyPositron
Welcome to PyPositron! This guide will walk you through creating your first project, understanding the example code, and building a simple code editor.
Step 1: Create the Example Project
To create the example project, follow the instructions in the Quick Start guide. If you have already created the example project, you can skip this step.
Step 2: Understand the Example Code
The example project consists of two main files:
backend/main.py
This file contains the Python logic for your application.
import py_positron as positron
import time
def main(ui: positron.PositronWindowWrapper):
button = ui.document.getElementById("button")
def on_click():
current_time = time.strftime("%H:%M:%S")
ui.document.alert(f"The current time is {current_time}")
button.addEventListener("click", on_click)
def after_close(ui: positron.PositronWindowWrapper):
print("Closing...")
positron.openUI("frontend/index.html", main, after_close, title="Example App")
main(ui: positron.PositronWindowWrapper)
- Called when the UI window starts loading.
ui.document.getElementById()
finds the button element by itsid
.- Defines an
on_click
callback that:- Gets the current system time.
- Formats it as
HH:MM:SS
. - Displays it via
ui.document.alert
.
- Attaches that callback to the button’s
"click"
event usingaddEventListener()
.
after_close(ui: positron.PositronWindowWrapper)
- This is optional.
- Called after the UI window is closed.
- Used for cleanup or logging.
- Here, it simply prints
"Closing..."
to the console.
frontend/index.html
This file contains the HTML and CSS for your application's user interface.
<!DOCTYPE html>
<html>
<head>
<title>Python-Powered App</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 20px;
}
button {
padding: 10px 20px;
font-size: 16px;
}
</style>
</head>
<body>
<h1>Welcome to PyPositron!</h1>
<button id="button">Click Me</button>
</body>
</html>
This is a fairly simple HTML file that:
- Sets the document type to HTML5.
- Defines a
<head>
section with a title and some basic CSS styles. - Contains a
<body>
section with a heading and a button.
Step 3: Modify the Example Code
Add a Textbox
Update frontend/index.html
to include a textbox:
<!-- in the body section of index.html -->
<h2>Type Something</h2>
<input type="text" id="textbox" placeholder="Type something...">
Example: Handle Key Press Events
We will update backend/main.py
to handle key press events:
# in main...
textbox = ui.document.getElementById("textbox") # Get the textbox element
def on_key_press():
value = textbox.value
print(f"You typed: {value}")
textbox.addEventListener("keypress", on_key_press)
- The
on_key_press
function retrieves the value of the textbox and prints it to the console whenever a key is pressed. - Then, we attach this function to the textbox's
"keypress"
event usingaddEventListener()
. - The
textbox.value
property is used to get the current text in the textbox. This property can also be used to set the value of the textbox programmatically.
Step 4: Build a Code Editor
Use a CSS Framework
To style your code editor, include a CSS framework like Bootstrap in frontend/index.html
:
<!--in the head section of index.html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
Add a Code Editor Area
Update frontend/index.html
to include a textarea for the code editor, a file path input, and a button to execute the code:
<div id="editor-container" class="container-fluid mt-3">
<label for="code-editor" class="form-label">Code Editor</label>
<textarea id="code-editor" class="form-control"></textarea>
</div>
<div class="container-fluid mb-3">
<label for="file-path" class="form-label mb-0">File Path</label>
<div class="d-flex align-items-center gap-3 mt-2">
<input type="text" id="file-path" class="form-control flex-grow-1">
<button id="save-button" class="btn btn-primary">Save</button>
<span id="save-button-span" class="text-success">No code saved yet. Press the save button.</span>
</div>
</div>
- The
<textarea>
element withid="code-editor"
will be used for writing code. - The
mb-3
class adds a bottom margin to the container. - Inside the
d-flex
container:- The
<input>
element withid="file-path"
allows the user to specify a file path where the code will be saved. - The
<button>
withid="save-button"
will trigger the save action. - The
<span>
withid="save-button-span"
will display feedback after saving the code. - The
flex-grow-1
class makes the input field take up the remaining space in the flex container.
- The
- The
d-flex
class makes the container a flexbox, allowing for easy alignment of its children.
Style the Code Editor
Create a new CSS file frontend/index.css
and link it in index.html
:
<!-- in the head section of index.html -->
<link rel="stylesheet" href="index.css">
Then, add some styles to frontend/index.css
:
html, body {
margin: 0;
padding: 0;
height: 100%;
display: flex;
flex-direction: column;
background: #121212;
color: #ffffff;
}
/* Editor container fills available space */
#editor-container {
flex: 1;
display: flex;
flex-direction: column;
}
label[for="code-editor"] {
margin-bottom: 5px;
}
#code-editor {
flex: 1;
width: 100%;
padding: 10px;
font-family: monospace;
font-size: 14px;
color: #ffffff;
background: #1e1e1e;
border: 1px solid #333;
border-radius: 0;
resize: none;
box-sizing: border-box;
}
/* Bottom controls */
.mb-3 {
padding: 10px;
}
input#file-path{
padding: 10px;
border-radius: 0;
}
button#save-button {
border-radius: 0;
}
- The
html
andbody
styles set the background color and text color for the entire page.- In this case, a dark theme is applied by making
background
black andcolor
(which is text color) white.
- In this case, a dark theme is applied by making
- The
#editor-container
fills the available space and uses flexbox to arrange its children vertically.- The
flex: 1
property allows the editor container to expand and fill the available vertical space. - The
display: flex
andflex-direction: column
properties make the container a flexbox that arranges its children in a column.
- The
- The
#code-editor
styles apply to the textarea:- A separate, lighter background color is applied to the editor container to differentiate it from the rest of the page.
width: 100%
ensures the textarea takes the full width of its container.- The
padding
property adds space inside the textarea for better readability. - The
font-family
is set tomonospace
for a code-like appearance. - Setting
border-radius: 0
gives it a square corner look. - The
resize: none
property prevents the user from resizing the textarea. By default, textareas can be resized by the user, but in this case, we want to keep it fixed in size.
Save Code
Update backend/main.py
to save the code written in the editor:
# in main...
code_editor = ui.document.getElementById("code-editor")
path_input = ui.document.getElementById("file-path")
def save_code():
code = code_editor.value
path = path_input.value
with open(path, "w") as f:
f.write(code)
save_button = ui.document.getElementById("save-button")
save_button.addEventListener("click", save_code)
- The
save_code
function retrieves the code from the textarea and the file path from the input field, then writes the code to the specified file. This is set as the click event handler for the save button. - The
.value
property of the textarea and input field is used to get their current values.
Final code
frontend/index.html
<!DOCTYPE html>
<html>
<head>
<title>Code Editor</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="index.css">
</head>
<body>
<div id="editor-container" class="container-fluid mt-3">
<label for="code-editor" class="form-label">Code Editor</label>
<textarea id="code-editor" class="form-control"></textarea>
</div>
<div class="container-fluid mb-3">
<label for="file-path" class="form-label mb-0">File Path</label>
<div class="d-flex align-items-center gap-3 mt-2">
<input type="text" id="file-path" class="form-control flex-grow-1">
<button id="save-button" class="btn btn-primary">Save</button>
<span id="save-button-span" class="text-success">No code saved yet. Press the save button.</span>
</div>
</div>
</body>
</html>
frontend/index.css
html, body {
margin: 0;
padding: 0;
height: 100%;
display: flex;
flex-direction: column;
background: #121212;
color: #ffffff;
}
/* Editor container fills available space */
#editor-container {
flex: 1;
display: flex;
flex-direction: column;
}
label[for="code-editor"] {
margin-bottom: 5px;
}
#code-editor {
flex: 1;
width: 100%;
padding: 10px;
font-family: monospace;
font-size: 14px;
color: #ffffff;
background: #1e1e1e;
border: 1px solid #333;
border-radius: 0;
resize: none;
box-sizing: border-box;
}
/* Bottom controls */
.mb-3 {
padding: 10px;
}
input#file-path{
padding: 10px;
border-radius: 0;
}
button#save-button {
border-radius: 0;
}
backend/main.py
import py_positron as positron
import time
def main(ui: positron.PositronWindowWrapper):
code_editor = ui.document.getElementById("code-editor")
path_input = ui.document.getElementById("file-path")
save_button_span = ui.document.getElementById("save-button-span")
save_button = ui.document.getElementById("save-button")
def save_code():
code = code_editor.value
path = path_input.value
with open(path, "w") as f:
f.write(code)
save_button_span.innerText = str(len(code.split("\n"))) + " lines of code saved to: " + path # Show feedback
save_button.addEventListener("click", save_code)
def after_close(ui: positron.PositronWindowWrapper):
print("Closing...")
positron.openUI("frontend/index.html", main, after_close, title="Code Editor")
Run and test the application
To run your application, like before, navigate to your project directory in the terminal and execute:
positron start
This will open the UI window defined in your backend/main.py
file, loading frontend/index.html
by default.
Congratulations! You have created a simple code editor application using PyPositron. You can now type code into the editor, specify a file path, and save the code to that file.
You can now use PyPositron to build more complex applications by adding more features and functionality.
Next Steps
- Library Reference: Learn more about PyPositron's classes and methods.
- Troubleshooting: Find solutions to common issues.
- Learn HTML, CSS, and JavaScript (Mozilla Developer Network): Familiarize yourself with web development basics to enhance your UI.
- Extend the code editor with features like syntax highlighting, file reading, a code execution feature and/or terminal, and a project/directory sidebar to select files.
- Build an actual app and share it with the community!