Skip to main content

AppModern

PyPI version License: MIT

AppModern é uma biblioteca Python para criar facilmente aplicações de desktop com interfaces web (HTML, CSS, JS), utilizando o poder do pywebview.

Visão Geral

A biblioteca abstrai a complexidade da comunicação entre Python e JavaScript, permitindo que você construa a interface do usuário com componentes Python que são renderizados dinamicamente no frontend.

Instalação

Você pode instalar o AppModern via pip:

pip install appmodern

Como Usar

Toda aplicação possui duas classes principais: App e api.

App Responsável por gerar a interface principal com a janela web.

Api Responsável pela comunicação entre o frontend e o backend Python..

App

O App é o núcleo da aplicação. Ele carrega a janela HTML do PyWebView e gerencia o conteúdo.

from appmodern.app import App

app = App(
    title="My Program",
    width=800,
    height=600,
    full_screen=False,
    debug=False,
    lang='en'
)

# Adiciona filhos extras à tag <head>
app.head.add_children(
    # Componentes como folhas de estilo ou scripts externos
)

# Inicializa a aplicação
app.run()

Componentes

A manipulação do DOM é feita através de componentes Python. Os principais são:

Tag (classe genérica para criação de elementos HTML)

ScriptExternal, StyleExternal, Meta, Title, Head, Body

from appmodern.components import Tag

# Classe personalizada baseada em uma <div>
class Div(Tag):
    pass

# Estrutura com filhos e atributos
class DivBlock(Tag):
    def __init__(self, parent, *children, **kwargs):
        """
        parent: seletor CSS para o elemento pai (ex: 'body', '#id', '.class')
        children: outros componentes (tags) filhos
        kwargs: atributos HTML (id, class_, style, value, etc.)
        """
        super().__init__(parent, *children, class_="exemplo", **kwargs)
        self.element = 'div'  # Corrige o nome da tag HTML

Observação: Por padrão, o nome da tag HTML será o nome da classe. Se necessário, sobrescreva self.element para garantir compatibilidade com o HTML

🧠 API

A Api é a classe responsável pela comunicação entre o backend (Python) e o frontend (JavaScript).
Ela atua com seis funções principais no Python e cinco no JavaScript, sendo elas:

  • route
  • call
  • create
  • read
  • update
  • delete

from appmodern import route, call, create, read, update, delete
from appmodern.components import Tag

# Criando componentes personalizados
class P(Tag): pass
class Button(Tag): pass

# Decorador para registrar uma rota que será chamada pelo frontend
# A função 'home' será executada automaticamente ao iniciar a aplicação
@route('home')
def sua_funcao(*args, **kwargs):
    # Cria um parágrafo na tag <body>
    create(P("body", "Texto"))

    # Lê elementos com base em seletores CSS
    # Filtros disponíveis: 'text', 'html', 'value', 'style'
    read('p', filter=['text', 'html', 'value', 'style'])

    # Atualiza o conteúdo de elementos com base em um seletor
    update(('p', P('body', "Atualiza aqui")))

    # Remove elementos do DOM com base em seletores
    delete('p')

    # Cria um botão com ação de clique que chama uma função Python
    create(Button('body', "Clique", onclick="call('clique')"))

# Rota que será chamada ao clicar no botão
@route('clique')
def uso_do_call(*args, **kwargs):
    # call() é uma função de comunicação entre front e back.
    # Pode ser usada em ambos os lados para invocar funções.
    # Parâmetros:
    #   call(nome_da_função, lista_de_args, dicionario_de_kwargs)

    call('funcao_de_apresentacao', ['arg1', 'arg2'], {"kwarg": 1})

Exemplo pratico

main.py

from appmodern.app import App
import exemples.home
app = App(
    title="AppModern Login",
    width=800,
    height=600,
    full_screen=False,
    debug=True,
    lang='pt-BR'
)

# Roda a aplicação
app.run()

home.py

#Componentes
from appmodern.components import Tag

class Div(Tag): pass
class Button(Tag): pass
class Input(Tag): pass
class Label(Tag): pass
class H1(Tag): pass
class P(Tag): pass


#Tela de login
from appmodern.components import Tag
from appmodern import route, create, read, update, delete, call
from time import sleep

# Componentes personalizados
class Div(Tag):
    def __init__(self, parent='body', *children, **kwargs):
        style = kwargs.pop("style", "") + """
            display: flex;
            flex-direction: column;
            align-items: center;
            background: #ffffff;
            padding: 30px;
            margin: 10% auto;
            width: 300px;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.2);
            font-family: 'Segoe UI', sans-serif;
        """
        super().__init__(parent, *children, style=style, **kwargs)

class Label(Tag):
    def __init__(self, parent='body', *children, **kwargs):
        style = kwargs.pop("style", "") + "margin-top: 12px; width: 100%; color: #444; font-weight: bold;"
        super().__init__(parent, *children, style=style, **kwargs)

class Input(Tag):
    def __init__(self, parent='body', **kwargs):
        style = kwargs.pop("style", "") + """
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            margin-top: 6px;
        """
        super().__init__(parent, style=style, **kwargs)

class Button(Tag):
    def __init__(self, parent='body', *children, **kwargs):
        style = kwargs.pop("style", "") + """
            background-color: #4facfe;
            color: white;
            border: none;
            padding: 12px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            margin-top: 20px;
            width: 100%;
        """
        super().__init__(parent, *children, style=style, **kwargs)

class H1(Tag): pass
class H2(Tag): pass
class P(Tag): pass

# Página inicial com formulário de login
@route('home')
def home_page():
    create(
        Div('body',
            H1(None, 'Login'),
            Label(None, "Login", Input(None, type="text", id='login')),
            Label(None, "Senha", Input(None, type="password", id='password')),
            Button(None, "Logar", onclick='call("logar")'),
            id='div-login'
        )
    )

# Função chamada ao clicar em "Logar"
@route('logar')
def logar():
    data = read('input', filter=['value'])
    login, password = data['data']

    if login[0] == 'gustavo' and password[0] == '123':
        call('bem-vindo', [login[0], 5])
    else:
        data = read('p')
        if not data['data']:
            create(P('#div-login', 'Login ou senha incorretos'))

# Simula tela de carregamento com contagem regressiva
@route('bem-vindo')
def bem_vindo(nome, segs):
    if segs == 5:
        delete('#div-login')
        create(
            Div('body',
                H1(None, 'Seja Bem-vindo'),
                P(None, f'{nome}, o programa ficará pronto em {segs}s'),
                id="div-bem-vindo"
            )
        )
        bem_vindo(nome, segs - 1)
    elif segs > 0:
        sleep(1)
        update(('p', P(None, f'{nome}, o programa ficará pronto em {segs}s')))
        bem_vindo(nome, segs - 1)
    else:
        update(('div#div-bem-vindo',
            Div(None,
                H1(None, "Logado com sucesso"),
                P(None, f"{nome}, seja muito bem-vindo ao novo sistema"),
                id="div-bem-vindo")
        ))
        create(H2('#div-bem-vindo', "AppModern"))

Licença

Este projeto está licenciado sob a Licença MIT. Veja o arquivo LICENSE para mais detalhes.

Metadata

Release files for appmodern 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for appmodern 0.2.0
File Size Uploaded Provenance
appmodern-0.2.0.tar.gz 15.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for appmodern 0.2.0
File Interpreter ABI Platform
appmodern-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.1 kB

Release files / appmodern-0.2.0.tar.gz

Download URL appmodern-0.2.0.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3603a1ccf8c026149eed372433f696d262161eebfb33c64c1b5734513a41743f
BLAKE2b-256 checksum
How to use checksums
d79274ec1ed464d0d675401eb82e04503ef4eee125eed3782ea03445fc43e2f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.5

Release files / appmodern-0.2.0-py3-none-any.whl

Download URL appmodern-0.2.0-py3-none-any.whl
Size 14.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5396d063e774c45e03a1e29dfb281b9b50d60b4a765f2e298f814f017f559c74
BLAKE2b-256 checksum
How to use checksums
f0e323abc980075d702b93af320188dcdbff9784135fac3a0f8c2ee7a11ce9e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.5

Security for appmodern 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page