用 Python MDL 开发时尚的 Material design 的网站

发布于:2022-12-19 ⋅ 阅读:(161) ⋅ 点赞:(0)

只用python也可以开发时尚的网站 😎😎😎
我们用javascript编写了一个简单但高效的python运行环境,让你无须使用javascript就可以编写网页。
你也无须直接使用html和css,我们提供一个python的库,里面提供基于谷歌 material design lite (MDL http://getmdl.io) 的布局和控件类,让你简单地组合它们就可以动态地产生最时尚的网站。
我们还自带了一个网页服务器,你的网站无须安装任何python依赖就可以跑起来 😎😎😎

展示

按钮

Column(
	Container(
	Row(
		Text(text=Icons.account_box, badge=Badge(text='1', overlap=True)),
		Text(text=Icons.account_box, badge=Badge(text='♥', overlap=True)),
		Text(text='Inbox', badge=Badge('4')),
		Text(text='Mood', badge=Badge('♥')),
		),
	margin=EdgeInsets.only(top=20),
	),
	Text(text='This link contains a badge', href='#', badge=Badge('7')),
	Row(
		Text(text='This link is followed by a badge', href='#'),
		Text(text='', badge=Badge('12')),
		),
	Text('This badge has too many characters.', href='#', badge=Badge('123456')),
	Text('This badge has no background color.', href='#', badge=Badge('123', no_background=True)),
	Button(Icons.add, fab=True, colored=True, action=action),
	Button(Icons.add, fab=True, ripple_effect=True, colored=True),
	Button(Icons.add, fab=True),
	Button(Icons.add, fab=True, ripple_effect=True),
	Button(Icons.add, fab=True, disabled=True),
	Button('Button', raised=True),
	Button('Button', raised=True, ripple_effect=True),
	Button('Button', raised=True, disabled=True),
	Button('Button', raised=True, colored=True),
	Button(Icons.add, 'Button', raised=True, accent=True),
	Button('Button', Icons.add, raised=True, accent=True, ripple_effect=True),
	Button('Button'),
	Button('Button', ripple_effect=True),
	Button('Button', disabled=True),
	Button('Button', primary=True),
	Button('Button', accent=True),
	Button(Icons.mood, icon=True),
	Button(Icons.mood, icon=True, colored=True),
	Button(Icons.mood, icon=True, accent=True),
	Button(Icons.add, mini_fab=True),
	Button(Icons.add, mini_fab=True, colored=True),

	Chip('Basic Chip'),
	Chip('Deletable Chip', close_button=True, action=action),
	Chip('Button Chip', button_chip=True, action=action),
	Chip('Contact Chip', contact='A'),
	Chip('Deletable Contact Chip', image='dog.png', close_button=True),
	)

卡片

Column(
	Card(CardTitle('Update', image='dog.png', image_right=0.15),
		CardText('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenan convallis.'),
		CardAction('View Updates', open_dialog1),
		width=420, height=320,
		color=Colors.black,
		background_color=Colors.green[100],
		shadow=2,
		),
	Card(CardTitle('Featured event:\nMay 24, 2016\n7-11pm'),
		CardAction('Add To Calendar', open_dialog2, Icons.event),
		width=256, height=256,
		color=Colors.white,
		background_color=Colors('#3E4EB8'),
		shadow=2,
		),
)

表格 

head = ['Material','Quantity','Unit price']
data = [
		['Acrylic (Transparent)', 25, '$2.90'],
		['Plywood (Birch)', 50, '$1.25'],
		['Laminate (Gold on Blue)', 10, '$2.35'],
		]
container = Container(
	Table(head, data),
	padding=EdgeInsets.only(bottom=20),
	)
def onchange(r,c,val1,val2):
	print('Table:',r,c,val1,val2)
	container.replace_child(Table(head, data))
Center(
	Container(
		Column(
			container,
			Table(head, data, editable=True, onchange=onchange),
			),
		padding=EdgeInsets.all(20),
		bg_color=Colors.grey[100],
		),
	)

 列表

Center(
	Container(
		Column(
			List(
				ListItem('Bryan Cranston'),
				ListItem('Aaron Paul'),
				ListItem('Bob Odenkirk'),
				),	
			List(
				ListItem('Bryan Cranston', icon=Icons.person),
				ListItem('Aaron Paul', icon=Icons.person),
				ListItem('Bob Odenkirk', icon=Icons.person),
				),
			List(
				ListItem('Bryan Cranston', avatar=Icons.person,
						action=Button(Icons.star, icon=True, primary=True)),
				ListItem('Aaron Paul', avatar=Icons.person,
						action=Button(Icons.star, icon=True, colored=True)),
				ListItem('Bob Odenkirk', avatar=Icons.person,
						action=Button(Icons.star, icon=True, accent=True)),
				),
			List(
				ListItem('Bryan Cranston', avatar=Icons.person,
						action=Checkbox(checked=True)),
				ListItem('Aaron Paul', avatar=Icons.person,
						action=RadioButton('item_name', checked=True)),
				ListItem('Bob Odenkirk', avatar=Icons.person,
						action=Switch(checked=True)),
				),
			List(
				ListItem('Bryan Cranston', sub_title='62 Episodes', avatar=Icons.person,
						action=IconToggle(Icons.star, checked=True)),
				ListItem('Aaron Paul', sub_title='62 Episodes', avatar=Icons.person,
						action=IconToggle(Icons.star)),
				ListItem('Bob Odenkirk', sub_title='62 Episodes', avatar=Icons.person,
						action=IconToggle(Icons.star)),
				),
			List(
				ListItem('Bryan Cranston', avatar=Icons.person,
						text_body='Bryan Cranston played the role of Walter in Breaking Bad. He is also known for playing Hal in Malcom in the Middle.',
						action=IconToggle(Icons.star, checked=True)),
				ListItem('Aaron Paul', avatar=Icons.person,
						text_body='Aaron Paul played the role of Jesse in Breaking Bad. He also featured in the "Need For Speed" Movie.',
						action=IconToggle(Icons.star)),
				ListItem('Bob Odenkirk', avatar=Icons.person,
						text_body='Bob Odinkrik played the role of Saul in Breaking Bad. Due to public fondness for the character, Bob stars in his own show now, called "Better Call Saul"',
						action=IconToggle(Icons.star)),
				),
			),
		width=600,
		padding=EdgeInsets.all(20),
		bg_color=Colors.grey[100],
		),
	)

输入控件

 

 

 

slider = Slider(disabled=True)
progress = Progress(disabled=True)
def slider_change(value):
	slider.change(value)
	progress.set_progress(value)
	progress.set_buffer(100-((100-value)//2))
def check_toast(value):
	print(f'value: {value}')
	toast(f'value: {value}')
Tab(sections=[
	Section('滑动条+进度条', Center(
		Container(
			Column(
				slider,
				Slider(value=50, onchange=slider_change),
				progress,
			),
			width=300,
			margin=EdgeInsets.all(30),
		),
	)),
	Section('复选框', Center(
		Column(
			Checkbox('Disabled', disabled=True),
			Checkbox('Control', onchange=check_toast),
		),
	)),
	Section('单选按钮', Center(
		Column(
			RadioButton('choice-1', 'First', onchange=check_toast),
			RadioButton('choice-1', 'Second', onchange=check_toast),
			RadioButton('choice-1', 'Third', onchange=check_toast),
		),
	)),
	Section('开关', Center(
		Column(
			Switch('First', checked=True, onchange=check_toast),
			Switch('Second', onchange=check_toast),
			Switch(disabled=True, onchange=check_toast),
			IconToggle(Icons.format_bold, checked=True, onchange=check_toast),
			IconToggle(Icons.format_italic, onchange=check_toast),
			IconToggle(Icons.format_bold, disabled=True, onchange=check_toast),
		),
	)),
	Section('文本框', Center(
		Column(
			Textfield('初始内容', label='文本...', onchange=check_toast),
			Textfield(label='数字...', onchange=check_toast, 
						pattern='-?[0-9]*(\\.[0-9]+)?',
						error='输入不是数字!'),
			Textfield(label='文本...', onchange=check_toast,
						floating_label=True),
			Textfield(label='数字...', onchange=check_toast, 
						pattern='-?[0-9]*(\\.[0-9]+)?',
						error='输入不是数字!',
						floating_label=True),
			Textfield(label='多行文本...', rows=3, onchange=check_toast),
			Textfield(label='多行文本...', rows=1, onchange=check_toast,
						floating_label=True),
			Textfield(label='多行文本 (最多6行)', rows=3, maxrows=6, 
						onchange=check_toast),
		),
	)),
	Section('下拉菜单', Center(
		Container(
			Column(
				Dropdown(['Some Action','Another Action','Yet Another Action'], 
					onchange=check_toast,
					textfield=Textfield(onchange=check_toast),
					),
				Dropdown(['Some Action','Another Action','Yet Another Action'], 
					onchange=check_toast,
					),
			),
		),
	)),
])

图标

from mdl_ import icons
import random
_icons = icons._icons
def sample_icons():
	# icons1 = random.sample(_icons, 200)
	icons1 = _icons
	return Grid([GridCell(Button(Icon(icon), icon=True, colored=True, action=_action(icon)), col=1) for icon in icons1])
def _action(icon):
	def action():
		toast('Icons.'+icon)
		# container.replace_child(sample_icons())
	return action
container = Container(sample_icons())

主题 

Themes(primary='deep_orange', accent='yellow').apply()

模版

 

项目内容

1. 一个简单的用js实现的python执行环境: web/lib/jswrt/py_full.js
    - web/index.html 
        - 调用python执行环境
        - 来运行主程序 web/main.py
2. 一个用python写的调用MDL的库: web/py_lib/*
3. 一个简单的http服务器,启动方法: 
    - 命令行 python3 -m serv
        - 第一次运行的时候会下载40MB的css文件到 web/lib/mdl/css
        - 为避免"删库跑路"的影响,这个项目的所有依赖都在本地
    - 浏览器 http://localhost:8000

在网页上运行 Python

关于我们用js实现的python执行环境:
- 编译和运行信息会显示在浏览器的控制台
    - 打开控制台的方法: 用google chrome的话可以点击:设置/更多工具/开发者工具
- 我们的简单python执行环境不包含所有python的功能
    - 包含 web/lib/jswrt/ 中两个pdf中介绍的内容,带笑脸符号的部分除外
    - 没有定义任何的操作符优先级
        - x+y+z 必须写成 (x+y)+z
        - x is not None and x>0 必须写成 (x is not None) and (x>0)
        - x<y<z 必须写成 (x<y) and (y<z)
    - 没有定义大部分的魔法函数,能使用
        - 算数相关的魔法函数
        - __init__, __repr__, __hash__, __setattr__, __getattr__
        - __iter__, __next__
        - __enter__, __exit__
        - __setitem__, __getitem__
        - 注意: 不支持 __del__
    - 要了解是否支持特定功能,可以使用我们的提供的调试网页
        - 命令行 python3 -m serv
        - 浏览器 http://localhost:8000/web/lib/jswrt/py_full.html

如何在网页上运行的python程序

    - 入口程序 web/main.py
    - 当在web/main.py上import模块时,执行环境会在web/py_lib中查找
    - 在这个web/main.py中,调用的是web/py_lib/mdl_test.py的run_app()

MDL 库的结构

    - web/py_lib/mdl.py是如果要使用MDL的话,需要先import的模块
        - mdl.py中进而import了py_lib/mdl_中定义的所有模块
    - web/py_lib/mdl_test.py中演示了mdl.py中定义的所有类的用法
        - web/py_lib/mdl_test_portfolio.py 重现了 https://getmdl.io/templates/portfolio/index.html 中的html+js例子
            - web/py_lib/mdl_test_icons.py 被使用于 web/py_lib/mdl_test_portfolio.py
        - web/py_lib/mdl_test_android.py 重现了 https://getmdl.io/templates/android-dot-com/index.html 中的html+js例子
        - 上面两个模块在 mdl_test.py 中的 299-305 行中被调用

源代码

MDL.zip

本文含有隐藏内容,请 开通VIP 后查看