def put_icon_buttons(icon_html: str, buttons: List[Dict[str, str]], onclick: Union[List[Callable[[], None]], Callable[[], None]]): value = buttons[0]['value'] return put_column([ output(put_html(icon_html)).style( "z-index: 1; margin-left: 8px;text-align: center"), put_buttons(buttons, onclick).style(f"z-index: 2; --aside-{value}--;") ], size="0")
async def main(): global chat_msgs set_env(title="PyWebIO Chat Room") put_markdown( "##PyWebIO聊天室\n欢迎来到聊天室,你可以和当前所有在线的人聊天。你可以在浏览器的多个标签页中打开本页面来测试聊天效果。" "本应用使用不到80行代码实现,源代码[链接](https://github.com/wang0618/PyWebIO/blob/dev/demos/chat_room.py)", lstrip=True) msg_box = output() with use_scope('msg-container'): style(put_scrollable(msg_box, max_height=300), 'height:300px') nickname = await input("请输入你的昵称", required=True, validate=lambda n: '昵称已被使用' if n in online_users or n == '📢' else None) online_users.add(nickname) chat_msgs.append( ('📢', '`%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users)))) msg_box.append( put_markdown('`📢`: `%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users)))) @defer_call def on_close(): online_users.remove(nickname) chat_msgs.append( ('📢', '`%s`退出聊天室. 当前在线人数 %s' % (nickname, len(online_users)))) refresh_task = run_async(refresh_msg(nickname, msg_box)) while True: data = await input_group('发送消息', [ input(name='msg', help_text='消息内容支持Markdown 语法', required=True), actions(name='cmd', buttons=['发送', { 'label': '退出', 'type': 'cancel' }]) ]) if data is None: break msg_box.append(put_markdown('`%s`: %s' % (nickname, data['msg']))) run_js( '$("#pywebio-scope-msg-container>div").animate({ scrollTop: $("#pywebio-scope-msg-container>div").prop("scrollHeight")}, 1000)' ) # hack: to scroll bottom chat_msgs.append((nickname, data['msg'])) refresh_task.close() toast("你已经退出聊天室")
async def main(): global chat_msgs put_markdown("## 🧊 Добро пожаловать в онлайн чат!") msg_box = output() put_scrollable(msg_box, height=300, keep_bottom=True) nickname = await input("Войти в чат", required=True, placeholder="Ваше имя", validate=lambda n: "Такой ник уже используется!" if n in online_users or n == '📢' else None) online_users.add(nickname) chat_msgs.append(('📢', f'`{nickname}` присоединился к чату!')) msg_box.append(put_markdown(f'📢 `{nickname}` присоединился к чату')) refresh_task = run_async(refresh_msg(nickname, msg_box)) while True: data = await input_group( "💭 Новое сообщение", [ input(placeholder="Текст сообщения ...", name="msg"), actions(name="cmd", buttons=[ "Отправить", { 'label': "Выйти из чата", 'type': 'cancel' } ]) ], validate=lambda m: ('msg', "Введите текст сообщения!") if m["cmd"] == "Отправить" and not m['msg'] else None) if data is None: break msg_box.append(put_markdown(f"`{nickname}`: {data['msg']}")) chat_msgs.append((nickname, data['msg'])) refresh_task.close() online_users.remove(nickname) toast("Вы вышли из чата!") msg_box.append(put_markdown(f'📢 Пользователь `{nickname}` покинул чат!')) chat_msgs.append(('📢', f'Пользователь `{nickname}` покинул чат!')) put_buttons(['Перезайти'], onclick=lambda btn: run_js('window.location.reload()'))
async def main(): """PyWebIO聊天室 和当前所有在线的人聊天 """ global chat_msgs put_markdown("## PyWebIO聊天室\n欢迎来到聊天室,你可以和当前所有在线的人聊天。你可以在浏览器的多个标签页中打开本页面来测试聊天效果。" "本应用使用不到80行代码实现,源代码[链接](https://github.com/wang0618/PyWebIO/blob/dev/demos/chat_room.py)", lstrip=True) msg_box = output() put_scrollable(msg_box, height=300, keep_bottom=True) nickname = await input("请输入你的昵称", required=True, validate=lambda n: '昵称已被使用' if n in online_users or n == '📢' else None) online_users.add(nickname) chat_msgs.append(('📢', '`%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users)))) msg_box.append(put_markdown('`📢`: `%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users)))) @defer_call def on_close(): online_users.remove(nickname) chat_msgs.append(('📢', '`%s`退出聊天室. 当前在线人数 %s' % (nickname, len(online_users)))) refresh_task = run_async(refresh_msg(nickname, msg_box)) while True: data = await input_group('发送消息', [ input(name='msg', help_text='消息内容支持行内Markdown语法'), actions(name='cmd', buttons=['发送', '多行输入', {'label': '退出', 'type': 'cancel'}]) ], validate=lambda d: ('msg', '消息不为空') if d['cmd'] == '发送' and not d['msg'] else None) if data is None: break if data['cmd'] == '多行输入': data['msg'] = '\n' + await textarea('消息内容', help_text='消息内容支持Markdown语法') msg_box.append(put_markdown('`%s`: %s' % (nickname, data['msg']), sanitize=True)) chat_msgs.append((nickname, data['msg'])) refresh_task.close() toast("你已经退出聊天室")
async def main(): global chat_msgs put_markdown("Добро пожаловать в онлайн чат\n" "Чат напсиан на языке Python\n" "`Copyright © Mamikon Papikyan`") msg_box = output() put_scrollable(msg_box, height=300, keep_bottom=True) nickname = await input("Войти в чат", required=True, placeholder="Ваше имя", validate=lambda n: "Такой ник уже используется" if n in online_users else None) online_users.add(nickname) chat_msgs.append(("🔉", f"`{nickname}` присоединился к чату!")) msg_box.append(put_markdown(f"`{nickname}` присоединился к чату!")) refresh_task = run_async(refresh_msg(nickname, msg_box)) while True: data = await input_group("Новое сообщение", [ input(placeholder="Текст сообщения", name="msg"), actions(name="cmd", buttons=["Отправить", {"label": "Выйти из чата", "type": "cancel"}] ) ], validate=lambda m: ("msg", "Введите текст сообщения") if "Отправить" == m["cmd"] and not m["msg"] else None ) if data is None: break msg_box.append(put_markdown(f"`{nickname}`: {data['msg']}")) chat_msgs.append((nickname, data['msg'])) # exit chat refresh_task.close() online_users.remove(nickname) toast("Вы вышли из чата") msg_box.append(put_markdown(f"🔉 Пользователь {nickname} покинул чат")) chat_msgs.append(("🔉", f"Пользователь {nickname} покинул чат")) put_buttons(["Перезайти"], onclick=lambda btn: run_js( "window.location.reload()"))
def basic_output(): set_env(title="PyWebIO Test") set_scope('top') put_markdown('### Basic') for i in range(3): put_text('text_%s' % i) put_text('测试空格:20空格:[%s]结束' % (' ' * 20)) for i in range(3): put_text('inline_text_%s' % i, inline=True) put_markdown("""### put_markdown 测试 `行内代码` 无序列表: - 北京 - 上海 - 天津 有序列表: 1. 北京 2. 上海 3. 天津 [链接](./#) ~~删除线~~ """, lstrip=True) put_link('链接', '#') put_text('<hr/>:') put_html("<hr/>") put_markdown('### Style') style(put_text('Red'), 'color:red') style([put_text('Red'), put_markdown('~~del~~')], 'color:red') put_table([ ['A', 'B'], ['C', style(put_text('Red'), 'color:red')], ]) put_collapse('title', style([ put_text('text'), put_markdown('~~del~~'), ], 'margin-left:20px'), open=True) put_markdown('### Table') put_table([ ['Name', 'Gender', 'Address'], ['Wang', 'M', 'China'], ['Liu', 'W', 'America'], ]) put_table([ ['Wang', 'M', 'China'], ['Liu', 'W', 'America'], ], header=['Name', 'Gender', 'Address']) put_table([ { "Course": "OS", "Score": "80" }, { "Course": "DB", "Score": "93" }, ], header=["Course", "Score"]) put_table([ { "Course": "OS", "Score": "80" }, { "Course": "DB", "Score": "93" }, ], header=[("课程", "Course"), ("得分", "Score")]) img_data = open(path.join(here_dir, 'assets', 'img.png'), 'rb').read() put_table( [['Type', 'Content'], ['text', '<hr/>'], ['html', put_html('X<sup>2</sup>')], ['buttons', put_buttons(['A', 'B'], onclick=None, small=True)], ['markdown', put_markdown('`awesome PyWebIO!`\n - 1\n - 2\n - 3')], ['file', put_file('hello.text', b'')], ['image', put_image(img_data)], [ 'table', put_table([['A', 'B'], [put_markdown('`C`'), put_markdown('`D`')]]) ]]) put_markdown('### Code') with use_scope('scroll_basis'): put_code( json.dumps(dict(name='pywebio', author='wangweimin'), indent=4), 'json') put_text('move ⬆ code block to screen ... :') with use_scope('scroll_basis_btns'): put_buttons(buttons=[ ('BOTTOM', Position.BOTTOM), ('TOP', Position.TOP), ('MIDDLE', Position.MIDDLE), ], onclick=lambda pos: scroll_to('scroll_basis', pos)) def show_popup(): popup('Popup title', [ put_html('<h3>Popup Content</h3>'), 'html: <br/>', put_table( [['Type', 'Content'], ['html', put_html('X<sup>2</sup>')], ['text', '<hr/>'], ['buttons', put_buttons(['A', 'B'], onclick=...)], ['markdown', put_markdown('`Awesome PyWebIO!`')], ['file', put_file('hello.text', b'')], ['table', put_table([['A', 'B'], ['C', 'D']])]]), put_buttons(['close_popup()'], onclick=lambda _: close_popup()) ], size=PopupSize.NORMAL) with use_scope('popup_btn'): put_buttons([('popup()', '')], onclick=[show_popup]) def edit_row(choice, row): put_text("You click %s button at row %s" % (choice, row), scope='table_cell_buttons') with use_scope('table_cell_buttons'): put_table([ ['Idx', 'Actions'], [ '1', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1)) ], [ '2', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2)) ], [ '3', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3)) ], ]) with use_scope('put_buttons'): put_buttons(['A', 'B', 'C'], onclick=partial(put_text, scope='put_buttons')) put_markdown('### Image') put_image(img_data) from PIL.Image import open as pil_open pil_img = pil_open(path.join(here_dir, 'assets', 'img.png')) put_image(pil_img, width="30px") put_image( 'https://cdn.jsdelivr.net/gh/wang0618/pywebio/test/assets/img.png', height="50px") put_file('hello_word.txt', b'hello word!') put_collapse('Collapse', [ 'text', put_markdown('~~删除线~~'), put_table([ ['商品', '价格'], ['苹果', '5.5'], ['香蕉', '7'], ]) ], open=True) put_collapse('title', 'something', open=True) put_scrollable('scrollable\n' * 20, height=50, keep_bottom=True) put_markdown('### Scope') with use_scope('scope1'): put_text("to be cleared") clear() put_text('A') # 输出内容: A put_text('B', position=0) # 输出内容: B A put_text('C', position=-2) # 输出内容: B C A with use_scope('scope2'): put_text('scope2') put_text('scope2') put_text('D', position=1) # 输出内容: B D C A put_text('before=top again', scope='top') with use_scope('to_remove'): put_text('to remove') remove('to_remove') put_markdown('### Info') session_info = get_info() from django.http import HttpRequest from flask import Request from tornado.httputil import HTTPServerRequest from aiohttp.web import BaseRequest request_type = { 'tornado': HTTPServerRequest, 'flask': Request, 'django': HttpRequest, 'aiohttp': BaseRequest, } request_ok = isinstance(session_info.request, request_type.get(session_info.backend)) if not request_ok: print( 'Error: request check error: backend %s, request type %s, class %s' % (session_info.backend, type( session_info.request).__name__, session_info.request)) put_markdown(rf"""### 会话信息 ``` * `user_agent`: * `is_mobile` (bool): {session_info.user_agent.is_mobile} * `is_tablet` (bool): {session_info.user_agent.is_tablet} * `is_pc` (bool): {session_info.user_agent.is_pc} * `is_touch_capable` (bool): {session_info.user_agent.is_touch_capable} * `browser.family` (str): {session_info.user_agent.browser.family} * `os.family` (str): {session_info.user_agent.os.family} * `os.version` (tuple): {session_info.user_agent.os.version} * `os.version_string` (str): {session_info.user_agent.os.version_string} * `device.family` (str): {session_info.user_agent.device.family} * `device.brand` (str): {session_info.user_agent.device.brand} * `device.model` (str): {session_info.user_agent.device.model} * `user_language` (str): {session_info.user_language} * `server_host` (str): {session_info.server_host} * `origin` (str): {session_info.origin or 'http://' + session_info.server_host} * `user_ip` (str): {session_info.user_ip} * `request type check` (str): {request_ok} ``` """, strip_indent=4) put_markdown('### Layout') put_row([ put_column([ put_code('A'), put_row([ put_code('B1'), None, put_code('B2'), None, put_code('B3'), ]), put_code('C'), ]), None, put_code('python'), None, style(put_code('python\n' * 20), 'max-height:200px;'), ]) put_grid([[ style(put_code('[%s,%s]' % (x, y)), 'margin-right:10px;') for y in range(4) ] for x in range(5)], direction='column') put_row([style(put_code(i), 'margin-right:10px;') for i in range(4)], 'repeat(auto-fill, 25%)') put_markdown('### Span') cell = lambda text: style(put_code(text), 'margin-right:10px;') put_grid([ [span(cell('A'), col=2), None], [span(cell('C'), row=2, col=2), span(cell('D'), row=2)], [], ], cell_width='1fr', cell_height='1fr') put_table([ ['C'], [span('E', col=2)], ], header=[span('A', row=2), 'B']) put_processbar('processbar', 0.3) set_processbar('processbar', 0.6) put_loading() # output hobby = output(put_text('Coding')) put_table([['Name', 'Hobbies'], ['Wang', hobby]]) hobby.reset(put_text('Movie')) hobby.append(put_text('Music'), put_text('Drama')) hobby.insert(0, put_markdown('**Coding**'))