[GH-ISSUE #923] How to execute a function one time after the tview.Application has completed the initialization? #674

Open
opened 2026-03-04 01:06:57 +03:00 by kerem · 2 comments
Owner

Originally created by @FJuedesOrcl on GitHub (Nov 27, 2023).
Original GitHub issue: https://github.com/rivo/tview/issues/923

Hi Friends,

not an issue, but an interesting question:

  • Writing an application that reads data from a Database, allows the User to edit the data and writes it back
  • The initial step is obviously loading the Data from the Database and instead of printing progress messages to os.Stderr i like to »write« those messages as rows into a table object.
  • That means, the application must have finished all of its initialization and the initial draw() of all the components.
  • I tried to use gv_App.QueueUpdate(LoadAll_Data) but that call never returns
  • I tried to use gv_App.QueueUpdate(func(){go LoadAll_Data()}) but that call never returns
  • I also tried to leverage the gv_App.SetAfterDrawFunc() but that caused the application to hang

Any ideas?

Originally created by @FJuedesOrcl on GitHub (Nov 27, 2023). Original GitHub issue: https://github.com/rivo/tview/issues/923 Hi Friends, not an issue, but an interesting question: - Writing an application that reads data from a Database, allows the User to edit the data and writes it back - The initial step is obviously loading the Data from the Database and instead of printing progress messages to os.Stderr i like to »write« those messages as rows into a table object. - That means, the application must have finished all of its initialization and the initial draw() of all the components. - I tried to use `gv_App.QueueUpdate(LoadAll_Data)` but that call never returns - I tried to use `gv_App.QueueUpdate(func(){go LoadAll_Data()})` but that call never returns - I also tried to leverage the `gv_App.SetAfterDrawFunc()` but that caused the application to hang Any ideas?
Author
Owner

@rivo commented on GitHub (Nov 27, 2023):

There's too little information for me to tell you what the problem is. The first question is when LoadAllData should be executed and whether it happens in the main goroutine or whether it needs to happen concurrently to some other tview stuff the user will work on. In the simplest scenario, you could load all data before starting up the tview application. Once that data is loaded, start a tview application and display the results in a table.

If, on the other hand, loading the data is triggered by the user — maybe by clicking a button — you could do it in response to that event, synchronously, and display a table with the results afterwards. But the application will not be responsive while the data is loading. No need to call QueueUpdate() in this case. QueueUpdate() is only needed if things happen concurrently.

If loading happens in a separate goroutine, then you can call QueueUpdateDraw() at the end to populate your table and cause the application to re-render the page.

There's a small Postgres demo application which might give you clues:

https://github.com/rivo/tview/wiki/Postgres

It's not great code but it may help you solve your problem.

<!-- gh-comment-id:1827220542 --> @rivo commented on GitHub (Nov 27, 2023): There's too little information for me to tell you what the problem is. The first question is when `LoadAllData` should be executed and whether it happens in the main goroutine or whether it needs to happen concurrently to some other `tview` stuff the user will work on. In the simplest scenario, you could load all data before starting up the `tview` application. Once that data is loaded, start a `tview` application and display the results in a table. If, on the other hand, loading the data is triggered by the user — maybe by clicking a button — you could do it in response to that event, synchronously, and display a table with the results afterwards. But the application will not be responsive while the data is loading. No need to call `QueueUpdate()` in this case. `QueueUpdate()` is only needed if things happen concurrently. If loading happens in a separate goroutine, then you can call `QueueUpdateDraw()` at the end to populate your table and cause the application to re-render the page. There's a small Postgres demo application which might give you clues: https://github.com/rivo/tview/wiki/Postgres It's not great code but it may help you solve your problem.
Author
Owner

@FJuedesOrcl commented on GitHub (Nov 27, 2023):

@rivo

Hi Friend,

Basically i am writing an application that allows end-users to edit a series of test-cases that are stored in multiple tables within a Database, so its download, edit, save-changes, quit.
Initially i was just downloading the data before the application started up and printing messages to stderr to indicate progress. As a result you could see the program printing something and before you had a chance the TUI would pop up, hiding the output.
Management didn't liked that…
They want me to display these messages in any kind of TUI element and i chose a table because it is already part of my TUI…
So it would be nice to have something like a one-time call-back function within the Application object, that indicates »hey i have initialized all UI-objects, everything has been drawn on the screen and you can start using the TUI.
What i came up with is somewhat hilarious and i don't like it:
I start the LoadAll_Data function right before calling EditApp.Run() as a go-routine.
The function then repeatedly calls Application.GetFocus(), waiting for the table object to be in focus
Then it waits for another second before opening the Database connection and printing feedback messages into the table-object.
It works, but the code looks messy and i don't like it. I'm sure that is not the intent of the Application.GetFocus() function…

Grüße aus West Virginia,
Frank/2

<!-- gh-comment-id:1828510126 --> @FJuedesOrcl commented on GitHub (Nov 27, 2023): @rivo Hi Friend, Basically i am writing an application that allows end-users to edit a series of test-cases that are stored in multiple tables within a Database, so its download, edit, save-changes, quit. Initially i was just downloading the data before the application started up and printing messages to stderr to indicate progress. As a result you could see the program printing something and before you had a chance the TUI would pop up, hiding the output. Management didn't liked that… They want me to display these messages in any kind of TUI element and i chose a table because it is already part of my TUI… So it would be nice to have something like a one-time call-back function within the Application object, that indicates »hey i have initialized all UI-objects, everything has been drawn on the screen and you can start using the TUI. What i came up with is somewhat hilarious and i don't like it: I start the LoadAll_Data function right before calling EditApp.Run() as a go-routine. The function then repeatedly calls Application.GetFocus(), waiting for the table object to be in focus Then it waits for another second before opening the Database connection and printing feedback messages into the table-object. It works, but the code looks messy and i don't like it. I'm sure that is not the intent of the Application.GetFocus() function… Grüße aus West Virginia, Frank/2
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#674
No description provided.