-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
654 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
name: Python and Flutter Build | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python 3.12.1 | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: 3.12.1 | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install -r requierements.txt | ||
- name: Set up Android SDK | ||
uses: android-actions/setup-android@v2 | ||
|
||
- name: Set up Flutter | ||
uses: subosito/flutter-action@v2 | ||
with: | ||
flutter-version: '3.19.0' # La versión de Flutter que estás utilizando | ||
|
||
- name: Build with Flet | ||
run: | | ||
flet build apk --product FletApp --project FletModel | ||
- name: Create Release | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: package | ||
path: | | ||
build/ | ||
dist/ | ||
bin/ | ||
lib/ | ||
include/ | ||
src/ | ||
if-no-files-found: error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,117 @@ | ||
# Flet-Model | ||
|
||
# Flet Model | ||
|
||
This repository contains a simple Flet application demonstrating a basic structure and usage of the Flet framework. | ||
|
||
## Repository Structure | ||
|
||
```plaintext | ||
Flet-Model/ | ||
├── assets | ||
│ └── icon.png | ||
├── core | ||
│ └── base.py | ||
├── views | ||
│ └── main_view.py (Add add all flet views here) | ||
├── main.py | ||
└── manifest.json | ||
``` | ||
|
||
### File Descriptions | ||
|
||
- **assets/icon.png**: Placeholder for assets like icons and images. | ||
- **core/base.py**: Contains the core classes and logic for the application. | ||
- **views/main_view.py**: Example view demonstrating the usage of the `Model` and `Control` classes. | ||
- **main.py**: Entry point for the Flet application, handling routing and initial setup. | ||
- **manifest.json**: Configuration file specifying application metadata and views. | ||
|
||
## Main Components | ||
|
||
### main.py | ||
|
||
This is the entry point of the application. It loads the configuration from `manifest.json`, dynamically imports the required modules, and sets up the routing and error handling. | ||
|
||
### core/base.py | ||
|
||
Defines the `Control` and `Model` classes which are used to represent UI components and views in the application. | ||
|
||
- **Control**: Wrapper for Flet controls with additional properties. | ||
- **Model**: Base class for creating views. It handles the creation and arrangement of `Control` instances. | ||
|
||
### views/main_view.py | ||
|
||
An example view demonstrating how to use the `Model` and `Control` classes. | ||
|
||
```python | ||
#main_view | ||
import flet as ft | ||
from core.base import Model, Control | ||
|
||
class MainView(Model): | ||
route = '/' | ||
|
||
appbar = ft.AppBar( | ||
leading=ft.Icon(ft.icons.PALETTE), | ||
leading_width=40, | ||
title=ft.Text("AppBar Example"), | ||
center_title=False, | ||
bgcolor=ft.colors.SURFACE_VARIANT, | ||
actions=[ | ||
ft.IconButton(ft.icons.WB_SUNNY_OUTLINED), | ||
ft.IconButton(ft.icons.FILTER_3), | ||
ft.PopupMenuButton( | ||
items=[ | ||
ft.PopupMenuItem(text="Item 1"), | ||
] | ||
), | ||
], | ||
) | ||
|
||
name = Control(ft.TextField(label="Name"), sequence=1) | ||
age = Control(ft.TextField(label="Age", keyboard_type=ft.KeyboardType.NUMBER), sequence=2) | ||
submit_button = Control(ft.ElevatedButton(text="Submit", on_click="on_click_submit"), sequence=3) | ||
|
||
def on_click_submit(self, e): | ||
print("Submitted") | ||
``` | ||
|
||
## Features | ||
- can be use for string for assign action in Control class | ||
- | ||
|
||
|
||
## Usage | ||
|
||
1. Clone the repository: | ||
```bash | ||
git clone https://github.com/fasilwdr/Flet-Model.git | ||
cd Flet-Model | ||
``` | ||
- Create views under views folder and map it into manifest.json | ||
```json | ||
{ | ||
"name": "Flet App", | ||
"short_name": "Flet App", | ||
"version": "1.0.1", | ||
"views": [ | ||
"views/main_view.py", | ||
"views/second_view.py" | ||
] | ||
} | ||
``` | ||
|
||
2. Install the required dependencies: | ||
```bash | ||
pip install flet | ||
``` | ||
|
||
3. Run the application: | ||
```bash | ||
flet main.py | ||
``` | ||
|
||
The application should start, and you will see a simple form with fields for Name and Age, and a Submit button. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import base | ||
from . import controls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import flet as ft | ||
|
||
|
||
class Control: | ||
""" | ||
A class to represent a control in a Flet application. | ||
Attributes: | ||
flet_control: The actual Flet control instance. | ||
visible (bool): Whether the control is visible. | ||
overlay (bool): Whether the control is an overlay. | ||
dialog (bool): Whether the control is a dialog. | ||
sequence (int): The sequence number for ordering controls. | ||
""" | ||
def __init__(self, flet_control, visible: bool = True, overlay: bool = False, dialog: bool = False, sequence: int = 1): | ||
self.flet_control = flet_control | ||
self.visible = visible | ||
self.overlay = overlay | ||
self.dialog = dialog | ||
self.sequence = sequence | ||
|
||
def __getattr__(self, item): | ||
# Delegate attribute access to the actual Flet control | ||
return getattr(self.flet_control, item) | ||
|
||
def __setattr__(self, key, value): | ||
if key in ["flet_control", "visible", "overlay", "dialog", "sequence"]: # Avoid infinite recursion for internal attributes | ||
super().__setattr__(key, value) | ||
else: | ||
setattr(self.flet_control, key, value) | ||
|
||
|
||
class Model: | ||
route = None | ||
back_route = None | ||
appbar = None | ||
bottom_appbar = None | ||
auto_scroll = None | ||
bgcolor = None | ||
drawer = None | ||
end_drawer = None | ||
fullscreen_dialog = False | ||
floating_action_button = None | ||
navigation_bar = None | ||
horizontal_alignment = ft.CrossAxisAlignment.START | ||
on_scroll_interval = 10 | ||
on_keyboard_event = None | ||
padding = 10 | ||
scroll = None | ||
on_scroll = None | ||
spacing = 10 | ||
vertical_alignment = ft.MainAxisAlignment.START | ||
|
||
def __init__(self, page): | ||
self.page = page | ||
|
||
def __post_init__(self): | ||
self.post_init() | ||
|
||
def on_view_pop(self, e): | ||
self.page.go(self.back_route) | ||
|
||
def init(self): | ||
# self.bgcolor = ft.colors.PRIMARY | ||
pass | ||
|
||
def post_init(self): | ||
pass | ||
|
||
def create_view(self): | ||
controls = [] | ||
# Collect all Control instances | ||
control_instances = [] | ||
for attr_name in dir(self): | ||
attr = getattr(self, attr_name) | ||
if isinstance(attr, Control): | ||
control_instances.append(attr) | ||
|
||
# Sort the controls based on their sequence | ||
sorted_controls = sorted(control_instances, key=lambda x: x.sequence) | ||
|
||
# Add sorted controls to the view | ||
for control in sorted_controls: | ||
actual_flet_control = control.flet_control | ||
for event in ['on_click', 'on_hover', 'on_long_press', 'on_change', 'on_dismiss']: | ||
if hasattr(actual_flet_control, event): | ||
callback_name = getattr(actual_flet_control, event) | ||
if isinstance(callback_name, str): | ||
method = getattr(self, callback_name, None) | ||
if method: | ||
setattr(actual_flet_control, event, method) | ||
if control.visible and not control.overlay and not control.dialog: | ||
controls.append(actual_flet_control) | ||
if control.overlay: | ||
self.page.overlay.append(actual_flet_control) | ||
if control.dialog: | ||
self.page.dialog = actual_flet_control | ||
if self.appbar and self.back_route: | ||
self.page.on_view_pop = self.on_view_pop | ||
self.appbar.leading = ft.IconButton(icon=ft.icons.ARROW_BACK, on_click=lambda e: self.page.go(self.back_route)) | ||
if self.on_keyboard_event: | ||
self.page.on_keyboard_event = None | ||
self.page.on_keyboard_event = self.on_keyboard_event | ||
|
||
self.init() | ||
return ft.View( | ||
route=self.route, | ||
controls=controls, | ||
appbar=self.appbar, | ||
bottom_appbar=self.bottom_appbar, | ||
auto_scroll=self.auto_scroll, | ||
bgcolor=self.bgcolor, | ||
drawer=self.drawer, | ||
end_drawer=self.end_drawer, | ||
fullscreen_dialog=self.fullscreen_dialog, | ||
floating_action_button=self.floating_action_button, | ||
horizontal_alignment=self.horizontal_alignment, | ||
on_scroll_interval=self.on_scroll_interval, | ||
padding=self.padding, | ||
scroll=self.scroll, | ||
spacing=self.spacing, | ||
vertical_alignment=self.vertical_alignment, | ||
navigation_bar=self.navigation_bar, | ||
on_scroll=self.on_scroll | ||
) | ||
|
||
|
||
def view_model(page): | ||
# Scan through subclasses of Model to find a matching route | ||
for cls in Model.__subclasses__(): | ||
if cls.route == page.route: | ||
return cls(page).create_view() # Pass the page object to the class | ||
# If no matching class is found | ||
raise ValueError("No view available for the given route") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import flet as ft | ||
from datetime import datetime, date | ||
|
||
|
||
def UserError(page, text): | ||
snackbar = ft.SnackBar(content=ft.Text(text, color=ft.colors.WHITE, text_align="center"), open=True, bgcolor=ft.colors.RED) | ||
page.show_snack_bar(snackbar) | ||
|
||
|
||
def UserInfo(page, text): | ||
snackbar = ft.SnackBar(content=ft.Text(text, color=ft.colors.WHITE, text_align="center"), open=True, bgcolor=ft.colors.BLUE) | ||
page.show_snack_bar(snackbar) | ||
|
||
|
||
def UserWarning(page, text): | ||
snackbar = ft.SnackBar(content=ft.Text(text, color=ft.colors.BLACK, text_align="center"), open=True, bgcolor=ft.colors.YELLOW) | ||
page.show_snack_bar(snackbar) | ||
|
||
|
||
def get_formated_date(date_string, format): | ||
date_object = datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%f") | ||
formatted_date = date_object.strftime(format) | ||
return formatted_date | ||
|
||
|
||
class DateField(ft.Container): | ||
def __init__(self, label, value='', col=None, format='%d-%m-%Y'): | ||
super().__init__() | ||
self.value = value | ||
self.format = format | ||
self.date_picker = ft.DatePicker( | ||
on_change=self.change_date, | ||
current_date=datetime.strptime(self.value, '%d-%m-%Y').date() if self.value else None, | ||
first_date=date(2023, 10, 1), | ||
) | ||
self.content = ft.Row(controls=[ | ||
ft.Text(label), | ||
ft.IconButton(ft.icons.DATE_RANGE, on_click=self.pick_date), | ||
ft.Text(self.value) | ||
]) | ||
self.col = col | ||
# self.border = ft.InputBorder.NONE | ||
self.padding = 5 | ||
self.bgcolor = ft.colors.SURFACE | ||
|
||
def pick_date(self, e): | ||
self.page.overlay.append(self.date_picker) | ||
self.page.update() | ||
self.date_picker.pick_date() | ||
def change_date(self, e): | ||
self.value = get_formated_date(e.data, self.format) | ||
self.content.controls[-1].value = self.value | ||
self.content.controls[-1].update() |
Oops, something went wrong.