First time contributor experience #1811
Replies: 4 comments 2 replies
-
Thanks a lot for sharing your experience, @frankhuurman! What a pity that you ran into #1809 which surprised us yesterday evening and was caused by a dependency of a dependency introducing a breaking change. We'll try to release a fix today. Regarding Docker setup and dev container: Hopefully we can further improve the documentation and dev environment to avoid similar confusion in the future. Personally I also just run main.py or test.py on my machine, but some developers expect a dev container so we added one in #1532. Overall I'm very happy that you had a rather good experience after all and quickly made progress creating a new UI element. 😊 |
Beta Was this translation helpful? Give feedback.
-
Another discussion about the same QBtnDropdown: #2470 :) |
Beta Was this translation helpful? Give feedback.
-
I just came across this discussion. Super interesting, I wonder what @frankhuurman's opinion would be on a thread that I just opened: #4847. As I am aiming to somehow help the process of first time (and hopefully not only) contributors to projects by somehow easing them into the project structure/architecture :) |
Beta Was this translation helpful? Give feedback.
-
Stumbled upon this thread. Let me talk about my experience: So my first PRs would be #4463 and #4466. They are driven by my desire of better speed, while running on slow hardware. Believing that we can make it faster, I peeked at the underlying source code. When I am familiar enough with that, I modified it, and it strengthened my understanding. Note: Motivation -> Understanding -> Implementation -> Experience. So, it's very important to be motivated! P.S.: I have mentioned that it resonates with the major I am taking, Integrative Systems and Design, for which NiceGUI allows the integration of the frontend and backend (incl. hardware components) into one neat package. See, I have also took a look at contributing to other libraries than NiceGUI, but nothing quite drives my passion than NiceGUI, and so I'm staying for now. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'd like to share a bit of my user & dev experience with NiceGUI here(I'll call it NG after this to abbreviate).
I've been a NG user ever since support for Mermaid charts was added which, at the time, was exactly what I needed to build a quick front-end that could show certain service & endpoint flows in our organization.
Besides suggesting some ideas and fixing exactly 1 documentation typo I had an urge to contribute a little bit more.
My end-goal idea is to build & integrate a nice looking audio recording element into the framework, but first I had to start somewhere easier to get my feet wet which is what I did the past 2 hours.
Stage 1 - preparation
I opened up the contributing file and figured I'd start at the top for once, instead of skimming through things and later on figuring out that I should have read it from the start anyways I'd do it straight away, so setting up the Dev Container it was!
I couldn't find the Remote-Containers extension in VS Code that was mentioned so opted for the (official Microsoft) Dev Containers extension instead, opened up the NG folder(already had it forked and ready with a venv), VS code suggested to start a dev container with it so I did. Not entirely sure how to use it to my advantage though, couldn't find the main.py site running and was a bit confused why I wouldn't just use the plain Docker option. Haven't used dev containers before but decided to read up on them tomorrow.
So I went to option 2: Plain old Docker. Or the
./docker.sh up app
command in the docs.✔ Container nicegui-app-1 Started
But it didn't seem to work properly, docker logs showed me
importlib.metadata.PackageNotFoundError: nicegui
which I didn't know how to solve quickly and I just wanted to do some developing.So I tried to launch main.py manually which, after installing the missing isort and docutils packages, actually worked!
Launched the browser and the NG site that we know in all its glory. All except the search functionality and dark/light mode seemed to be working. But I was fine with it as I could start to work through the framework a little bit.
Stage 2 - The Where, How and Why
I now decided on trying to implement the q-button-dropdown element from Quasar since it wasn't implemented yet and seemed like an element I might want to use in a navigation header on desktop. Like in a clothing webshop, having a navigation item called "Men" which when clicked on or hovered over drops down a menu with items like "Shoes", "Jeans", "Jackets" etc. Seemed useful enough!
So what's an example that is close to a q-button-dropdown? a q-button of course!
I searched for button through the NG folder I opened in VS Code and found button.py in nicegui/elements which seemed like a super obvious place to find it in hindsight.
Opened it up, understood about 50% of how it worked after skimming through it and decided to take this file as a base for q-button-dropdown so I copied it and renamed it to button_dropdown.py
My first question was, how does this element actually know what Quasar element to map to? I quickly found tag='q-btn' which seemed like the way to go. Searching through the open VS Code folder for
q-btn
made me aware of the static quasar.css file and when scrolling further down I saw that the.q-btn-dropdown
class was probably the one I needed.So I changed the tag to q-btn-dropdown and was like, ok... now.. how do I actually use it through a ui.something() method like the other elements?
After some searching I found the ui.py file which seemed to have a long list of element names in it, I added my own
button_dropdown
just afterbutton
in the list and was hoping this would do the trick.I opened up my trustworthy testy.py
Scribbled down some example code:
only to realize when running the script that there is no such attribute, cause I should have used ui.button_dropdown. Little derp, it's late, sleep is setting in.
I was also worried it wouldn't work because auto-complete and ctrl+click to go to the element didn't work which just turned out to be the wrong Python interpreter setting in the end.
The glorious rectified example code:
To my amazement and the black box that the "python-to-quasar-element" mapping still seems to be, the dropdown button actually showed up!

Well, sort of!
It didn't have any items in it of course and at first I didn't even know how to tackle adding a list of items to it. Does the
__init__
need anotheroptions
parameter to accept a List or Union when creating it? how does the mapping work for that?I looked through the Quasar documentation but couldn't find any content options to pass to it, but they did suggest looking at their Select component if one needed
input
instead ofbutton-like
usage. This made me think of the ui.select/ui.menu elements that NG already had so I decided to take a look at the Menu element and voila! It had some extra methods for interactivity on the Menu element itself, plus an extra class with theq-item
tag that represent the items for the menu.I decided to copy some of the code and imports, changed it to fit the dropdown button names and added the dropdown_button_item to work in the same way as the Menu element does. I imported
ButtonDropdownItem as button_dropdown_item
in ui,py and even forgot to put it in the__all__
list at the top of the file but ran the example again while expanding the example script to:And while not even expecting this to just work that easily, I got this amazing result out of it:
2023-10-16.00-16-44.mp4
Stage 3 - To the future and beyond!
So far it looks like the dropdown items aren't yet triggering any clicks, I tried a lambda with a ui.notify which didn't work. But now that I'm writing this, the regular ui.button also doesn't seem to trigger it anymore, not even when I remove all code and only try the NG docs example of it.
Might have something to do with the terminal logging:
nicegui.py:141: RuntimeWarning: coroutine 'AsyncServer.enter_room' was never awaited sio.enter_room(sid, client.id)
But I guess that's something for future me to figure out!
Hope you guys enjoyed the story of my fumbling around with my first steps into contributing to the framework and can learn something from it when starting out yourselves. I'm aiming to finish this element to get a more clear understanding of things before I start working on the audio recorder one.
Have a nice day 😄
Beta Was this translation helpful? Give feedback.
All reactions