Create a dialog for non-blocking showing progress out of a text file
#1
Hi there,

creating a custom dialog which would show informations from a file content is no problem indeed, but how can I make it update itself non-blocking periodically for, lets say, every second?

Similar to what I would do in Ajax with setInterval(<function/script to call>,<period in ms>)

Is there some strategy or other addons that have a solution like this?

For making it clear: Just push some notification from time to time is not really what I want. I want the user to be able to follow a progress similar to DialogProgress(), like mentioned in http://kodi.wiki/view/HOW-TO:Write_Pytho...rogressbar, but non-blocking, so that the user can come to this dialog from time to time but is able to do other things in kodi in the meantime.

Hope anyone of you can give me the right kickoff :-)

Thx
Reply
#2
Not possible AFAIK. Not the update content part - that is relatively simple, but a non-blocking window. The best you can have is a window that you can open/close whenever you want. As for updating window contents, you can do it from a secondary thread. I was assured that it was thread-safe (unlike in "real" desktop GUI frameworks).
Reply
#3
Hi Roman,

thx for the quick reply. The task here is about to show a download progress (or many of them).

(2016-01-22, 17:09)Roman_V_M Wrote: Not the update content part - that is relatively simple

Thought exactly this would be the tricky part. How would I do the (periodically) update thing? Any link or so?

(2016-01-22, 17:09)Roman_V_M Wrote: but a non-blocking window. The best you can have is a window that you can open/close whenever you want. As for updating window contents, you can do it from a secondary thread

I would have no problem if the user opens up a dialog, getting current state of downloading and as long he/she stays in this dialog the state is updated. If the user has enough of watching progresses, he should be able to leave the dialog (closing it) and do other things in kodi.

The jobs theirselves are still running in the background because, for instance, they are external scripts that had been startet via buildin RunScript mechanism which is non-blocking by deefault referring to documentation. The frontend dialog should only be for updated reading json/xml-Files and displaying them in a user-friendly manner.

It should be a "Lets-see-how-far-my-jobs-are"-Dialog which can be opened anytime the user wants to.

So following these specs it should be possible, if I got you right. But where to start?

Best
Reply
#4
It depends on your actual task. If you need to display some progress indicator and a couple lines of text, then xbmcgui.DialogProgress will be enough. It works in a separate thread by design, so you just need to call update() periodically from your code.

If you need a more complex info dialog, then you have to create a custom dialog window based on xbmcgui.WindowDialog and organize your update thread all by yourself.

Below is a slightly modified example from my PyXBMCt framework topic (I prefer my own mini-library over vanilla xbmcgui classes):
PHP Code:
# Import PyXBMCt module.
import pyxbmct
import threading
import time


def update_label
(windowlabel):
    
"""
    Update label text
    """
    
for i in xrange(011):
        
label.setLabel('Count: {0}'.format(i))
        
time.sleep(1.0)
    
label.setLabel('Goodbye!')
    
time.sleep(1.0)
    
window.close()


# Create a window instance.
window pyxbmct.AddonDialogWindow('Hello, World!')
# Set the window width, height and the grid resolution: 2 rows, 3 columns.
window.setGeometry(35015023)
# Create a text label.
label pyxbmct.Label(''alignment=pyxbmct.ALIGN_CENTER)
# Place the label on the window grid.
window.placeControl(label00columnspan=3)
# Create a button.
button pyxbmct.Button('Close')
# Place the button on the window grid.
window.placeControl(button11)
# Set initial focus on the button.
window.setFocus(button)
# Connect the button to a function.
window.connect(buttonwindow.close)
# Connect a key action to a function.
window.connect(pyxbmct.ACTION_NAV_BACKwindow.close)
#========================
update_thread threading.Thread(target=update_labelargs=(windowlabel))
update_thread.daemon True
update_thread
.start()
#=======================
# Show the created window.
window.doModal()
# Delete the window instance when it is no longer used.
del window 
This will display countdown from 0 to 10 and then close the window itself.
The only problem with this variant is that you won't be able to use a progress indicator because xbmcgui.ControlProgress is broken.

PS. You can also use a skinned xbmcgui.WindowXMLDialog, but I'm no expert on Kodi skin-related matters so I won't help you here.
Reply
#5
(2016-01-22, 18:35)Roman_V_M Wrote:
Code:
update_thread = threading.Thread(target=update_label, args=(window, label))
update_thread.daemon = True

This was a good hint, so I can use the update_label method to check the external process is running and as log as this is the case reading a file Smile

You wrote:
(2016-01-22, 18:35)Roman_V_M Wrote: This will display countdown from 0 to 10 and then close the window itself.

Am I able to close the window-dialog BEFORE 10 is reached. Lets say I see 2, close the dialog and then reenter the dialog and follow the progress til the end, lets say from 6 to 10 until it closes itself. This is what I meant with non-blocking.

If this is possible, I think I have all thre ingredients I need Big Grin

Can you confirm that it would work this way?

My actual task would be then:

Triggering a download script from somewhere else in Kodi (a List-Entry), which starts a download process in the background which itself periodically fills data into a json file.

Then there is another List entry, call it "Downloads" which opens up our self build Dialog. This dialog is just for periodically reading the json file and display its current status information (what the update_label function could do)

Displaying more then one job I would rather do in a kodi standard list, which just reads the existing "job-files". It all depends on if this dialog is always closable.

Thanks so far anyway Smile
Reply
#6
(2016-01-22, 19:33)liberavia Wrote: Am I able to close the window-dialog BEFORE 10 is reached. Lets say I see 2, close the dialog and then reenter the dialog and follow the progress til the end, lets say from 6 to 10 until it closes itself. This is what I meant with non-blocking.

Of course! A window instance is not invalidated after calling close(), it just hides from sight, and the update thread continues to work in background.

There is one thing, though. In a real plugin you need to implement some signals to secondary threads to abort them, e.g. when you exit your addon or Kodi in general. Python in Kodi doesn't seem to honor daemon = True flag.
threading.Event class can be used for simple signalling between threads, and xbmc.abortRequested is a signal from Kodi that it is going to close.
Reply
#7
Great to hear. Well I guess teh mentioned misbehaviour is more an advantage for me than a disadvantage Big Grin

I will put the PID into the infofile, so I can directly kill the task.

However, yesterday I implemented a simple solultion which indeed won't bring me to the thing I want, but maybe useful for others:

For just having a simple kodi standard Backgroound downloader, you can use this code:

Code:
def MyDownloader(url,dest,headline,subline):
    dp = xbmcgui.DialogProgressBG()
    dp.create(headline, subline)
    urllib.urlretrieve(url,dest,lambda nb, bs, fs, url=url: _pbhook(nb,bs,fs,url,dp))
    dp.close()

def _pbhook(numblocks, blocksize, filesize, url=None,dp=None):
    percent = min((numblocks*blocksize*100)/filesize, 100)
    print percent
    dp.update(percent)

To use this, simply call

Code:
MyDownloader("http://www.example.org/myhugezipfile.zip","/path/to/target/mytarget.zip","My Headline", "My Subline")

As mentioned I will work with Romans approach, due I need to implement Download-Processes of many different kinds. I will post the code here If I found a solution.
Reply

Logout Mark Read Team Forum Stats Members Help
Create a dialog for non-blocking showing progress out of a text file0