Replies: 2 comments 1 reply
-
|
Hi @dridk,
Why not? Here's a quick example of a similar setup: from nicegui import events, ui
class Preview:
def __init__(self) -> None:
self.label = ui.label('Preview')
def update_preview(self, content: str) -> None:
self.label.text = f'You are viewing "{content}"'
class ItemList:
def __init__(self, preview: Preview) -> None:
self.preview = preview
self.data = [{'name': 'Item 1'}, {'name': 'Item 2'}, {'name': 'Item 3'}]
self.table = ui.table(rows=self.data)
self.table.on('row-click', self.on_row_click)
def filter(self, query: str) -> None:
self.table.rows = [row for row in self.data if query in row['name']]
def on_row_click(self, event: events.GenericEventArguments) -> None:
_, row, _ = event.args
self.preview.update_preview(row['name'])
class SearchBar:
def __init__(self, item_list: ItemList) -> None:
self.item_list = item_list
with ui.row(align_items='center'):
self.input = ui.input('Search for items ...')
self.button = ui.button('Search', on_click=self.search)
def search(self) -> None:
self.item_list.filter(self.input.value)
self.input.value = ''
def root():
preview = Preview()
with ui.left_drawer().classes('bg-slate-100'):
item_list = ItemList(preview)
with ui.header().classes('bg-slate-200'):
SearchBar(item_list)
ui.run(root) |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
Whaoo! Looks so easy ! But in your example, Preview cannot access to the SearchBar. The declaration order is important for both communication and UI. I tried myself in a different way, using Event ! It looks similar than signals and slot from Qt. # Qt syntax
widget1.clicked.connect(widget2.refresh)
# NiceGUI hack syntax
widget1.clicked.subscribe(widget2.refresh)Here is my code ! Look at the end from nicegui import ui, binding, observables, Event
from random import randint
class DataModel:
def __init__(self):
self.query = ""
self.on_populate = Event()
self.populate()
def populate(self):
self.df = [{"name": "Bob", "age": randint(0, 100)}]
self.on_populate.emit()
class SearchBar:
def __init__(self, model):
self.model = model
def render(self):
with ui.row().classes("w-full flex justify-center items-center gap-0 bg-white"):
ui.input(label="Enter search ..").bind_value(self.model, "query").props(
"outlined"
)
ui.button("Search", on_click=self.model.populate).props("flat")
class TableView:
def __init__(self, model):
self.model = model
self.table = None
self.on_name_clicked = Event[str]()
def render(self):
with ui.column().classes("bg-red") as layout:
with ui.row():
ui.button("refresh", on_click=self.refresh)
ui.button("clear", on_click=self.clear)
self.table = ui.table(rows=self.model.df).classes("w-full")
self.table.on(
"row-click", lambda e: self.on_name_clicked.emit(e.args[1]["age"])
)
ui.label().bind_text_from(
self.model, "query", backward=lambda x: f"You are looking for {x}"
)
return layout
def clear(self):
if self.table:
self.table.rows.clear()
def refresh(self):
if self.table:
self.table.rows = self.model.df
class Viewer:
def __init__(self, model):
self.model = model
def render(self):
with ui.row() as layout:
self.editor = ui.editor().classes("w-full")
return layout
def set_name(self, name: str):
self.editor.set_value(name)
@ui.page("/")
def app():
# Create variable
model = DataModel()
bar = SearchBar(model)
listview = TableView(model)
view = Viewer(model)
# Create UI
ui.query(".nicegui-content").classes("p-0")
with ui.element("div").classes("w-screen h-screen bg-blue"):
# Add Search bar
bar.render()
with ui.row().classes("w-full gap-2 mt-10 justify-around"):
listview.render().classes("w-1/3")
view.render().classes("w-1/3")
# Connection
model.on_populate.subscribe(listview.refresh)
listview.on_name_clicked.subscribe(view.set_name)
ui.run() |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
First Check
Example Code
Description
Hi,
I have experience in graphical user interfaces with libraries such as Qt and a little bit of Vue.JS.
I am used to organizing my code into components that interact with each other using signals and slots.
Nicegui is really good, but I'm having trouble figuring out how to organize my code into composite elements.
For example, let's imagine a simple search application with a search bar at the top, a list of items on the left, and an item viewer of on the right. When I click on search, it updates the list. When I click on an item in the list , it updates the preview.
To make the code clear, I have 3 components: SearchBar() , ListItemView() and ItemViewer() .
How am I supposed to refresh the ListItemView when I click on the search button and refresh the ItemViewer when I click on a row ?
With other frameworks, we would create classes with methods. But I don't think we can do that with nicegui. It forces me to write spaghetti code.
NiceGUI Version
3.3.1
Python Version
3.13
Browser
Firefox
Operating System
Linux
Additional Context
No response
Beta Was this translation helpful? Give feedback.
All reactions