Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Development

Notices

Reply
 
Thread Tools Search this Thread
Old 08-18-2012, 05:59 PM   #1
jackie_w
Grand Sorcerer
jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.
 
Posts: 6,212
Karma: 16534894
Join Date: Sep 2009
Location: UK
Device: Kobo: KA1, ClaraHD, Forma, Libra2, Clara2E. PocketBook: TouchHD3
Help with python QProgressBar, please.

Please can someone help me with a Python problem?

In my user interface plugin's main processing file the basic code looks something like this
Code:
class CopyCoverUiAction(InterfaceAction):
    ... ...
    def genesis(self): ... ...
    def apply_settings(self):  ... ...
    ... ...
    def copycover_selected(self):
        # some validation actions
        # get user selected book rows
        
        for book in range(len(rows)):
            # process the book
            
        # some end actions
        # open a QTextBrowser info dialog to display results
The user cannot do anything during the processing until the final info dialog box is displayed and needs to be manually closed. I'd like to keep it this way.

However, for some devices the book looping can be quite lengthy if many books are selected (max 99), and from a user POV it can appear that calibre isn't doing anything and is unresponsive. So what I want to do is add some kind of progress bar pop-up, starting just before the loops start, ending just after the loops finish and being updated once at the end of each cycle.

I've tried to get a QProgressBar() working but I'm obviously doing it wrong. In fact I've tried so many different combinations that I'm now completely scrambled. For the sake of my sanity please can someone show me some sample code of how to set up a simple ProgressBar with appropriate signals/slots so that the bar opens, visibly updates at the completion of each cycle then closes without any user interaction. The limited amount of python/Qt sample code I've found on Google, if it works at all, is using timer intervals or other widgets to update the Progbar and I'm not sure that's what I need.

I've also looked at some calibre source code but am not able to see the wood for the trees.

I've managed to pick up (I think) some basics like
self.pb = QProgressBar(self)
self.pbar.setRange(0, len(rows))
self.pbar.setValue(int step)
but am totally unable to arrange them into something that works. I also know that event handling can be complex and my OOP skills are very limited. So if there is a simple, robust way forward I'd be most grateful.

P.S. In some of my own non-calibre python experiments I've had some success with progressive screen updating using this piece of magic code QApplication.instance().processEvents() (thanks to chaley) but I'm not sure how to apply it in this case.
jackie_w is offline   Reply With Quote
Old 08-18-2012, 06:05 PM   #2
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,636
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
Have a look at the Quality Check plugin source code - specifically "dialogs.py" and copy/modify the "QualityProgressDialog" class which is at the top of the file. Basically you just do your work inside that "do_book_action" function, and that self.i counter and self.setValue stuff increments the progress bar, using QTimer.singleShot to ensure it pumps the message threads to keep the UI updated while it does the work.

It is invoked from the check_base.py file, inside the "check_all_files" function - just a case of instantiating it passing in whatever parameters it needs to do the work. In the case of this plugin it passes in a callback_fn parameter, being a function pointer reference to a dynamically chosen function (since the same dialog is redisplayed for a whole range of different purposes) but you can ignore that and do the work inside the dialog itself if you want as I mentioned above.

It is a pattern I have used over and over again in my plugins, many of them have it.
kiwidude is offline   Reply With Quote
Advert
Old 08-18-2012, 06:12 PM   #3
jackie_w
Grand Sorcerer
jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.
 
Posts: 6,212
Karma: 16534894
Join Date: Sep 2009
Location: UK
Device: Kobo: KA1, ClaraHD, Forma, Libra2, Clara2E. PocketBook: TouchHD3
You are one fast reader, kiwidude Shouldn't you be out on the town in the hotspots of London?

Thank you so much. I'll try to make sense of it. I can't promise I won't be back though.
jackie_w is offline   Reply With Quote
Old 08-18-2012, 06:16 PM   #4
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,636
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
Probably "should" be but not my scene really, peace and quiet at home preferred to competing with the countless drunken hordes ejected from the pubs as London shuts down about now...
kiwidude is offline   Reply With Quote
Old 08-19-2012, 01:05 PM   #5
jackie_w
Grand Sorcerer
jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.
 
Posts: 6,212
Karma: 16534894
Join Date: Sep 2009
Location: UK
Device: Kobo: KA1, ClaraHD, Forma, Libra2, Clara2E. PocketBook: TouchHD3
Just a follow-up to say that everything seems to be working Thanks for your help.
jackie_w is offline   Reply With Quote
Advert
Old 09-03-2012, 10:07 AM   #6
Pepin33
Zealot
Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.
 
Posts: 109
Karma: 419
Join Date: Aug 2012
Location: Spain
Device: Kindle Touch
I was using a QProgess Bar, after looking kiwidude's Quality Check plugin.

I works OK, but I have a problem when the user cancel the process. I assign the progressbar object, and then I do "progressbar.exec_()". The function assigned to QTimer.singleShot makes it work, but if the user closes the window, the function continues executing (and obviously, I get some errors).

I tried hidding "cancel" and "close" buttons, but if the user press "ESC" the window still closes.

Somebody can help me?
Pepin33 is offline   Reply With Quote
Old 09-03-2012, 10:32 AM   #7
jackie_w
Grand Sorcerer
jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.
 
Posts: 6,212
Karma: 16534894
Join Date: Sep 2009
Location: UK
Device: Kobo: KA1, ClaraHD, Forma, Libra2, Clara2E. PocketBook: TouchHD3
At the risk of the blind leading the blind, this is what I did after having looked at kiwidude's Quality Check code.

I used a QProgressDialog rather than QProgressBar.

This was the dialog:

Code:
class CoverProgressDialog(QProgressDialog):

    def __init__(self, gui, total_books, some_more_params):
        self.total_books = total_books
        QProgressDialog.__init__(self, '', QString('Cancel'), 0, self.total_books, gui)
        self.gui = gui
        # ... ...
        self.i = 0
        # ... ...      
        QTimer.singleShot(0, self.do_book_action)
        self.exec_()

    def do_book_action(self):
        if self.wasCanceled():
            return self.do_close()
        if self.i >= self.total_books:
            return self.do_close()

        # code for processing a single book ...

        self.i += 1
        self.setLabelText('%d of %d' % (self.i, self.total_books))
        self.setValue(self.i)
        QTimer.singleShot(0, self.do_book_action)

    def do_close(self):
        self.hide()
        self.gui = None
and this was the code which called the dialog
Code:
dlg = CoverProgressDialog(self.gui, total_books, some_more_params)
if dlg.wasCanceled():
    # do whatever should be done if user cancelled
Hope this helps
jackie_w is offline   Reply With Quote
Old 09-03-2012, 10:45 AM   #8
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,636
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
@jackie_w - I think that would be "the blind leading the blind leading the blind"
kiwidude is offline   Reply With Quote
Old 09-03-2012, 11:01 AM   #9
jackie_w
Grand Sorcerer
jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.
 
Posts: 6,212
Karma: 16534894
Join Date: Sep 2009
Location: UK
Device: Kobo: KA1, ClaraHD, Forma, Libra2, Clara2E. PocketBook: TouchHD3
Quote:
Originally Posted by kiwidude View Post
@jackie_w - I think that would be "the blind leading the blind leading the blind"
You'll do for me. If I'd had to rely on the PyQt online documentation, I'd still be reading... it strikes me as a wonderful resource for those who already know most of the answers.

... which brings me to another question, is there a good manual for learning about PyQt, with lots of examples?

I found 'Rapid GUI Programming with Python and Qt' by Mark Summerfield. The early chapters were good enough to give me a very basic toolkit, but it soon got beyond me
jackie_w is offline   Reply With Quote
Old 09-03-2012, 12:52 PM   #10
Pepin33
Zealot
Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.
 
Posts: 109
Karma: 419
Join Date: Aug 2012
Location: Spain
Device: Kindle Touch
jackie_w, I do the same way than you do (I also look at kiwidude's code).

The only difference is that I don't have a cancel button, so I never had a self.wasCanceled() true value.

But the problem is when the user doesn't cancel, but closes the window. Try with your code, when the bar is on screen, if you press "ESC" or push the X button, the window closes, but it doesn't produces a "Cancel" event (maybe because you're not canceling, but closing). I found the way to hide the close button, but the "ESC" key still closes it.

In my case, the code in the function "do_book_action" (in your example), continues executing when the progress bar window is closed at this way, and the execution at the main window continues.

The process I was doing is to uncompress a ZIP file to a temporary folder, then the progress bar shows when adding some books to the library, and at last it closes, and I delete the temporary files from the main window. When the user closes the progress bar window before the process is finished, the function who add books continues, but the code at the main window deletes the files, so I get lots of errors.

Last edited by Pepin33; 09-03-2012 at 12:56 PM.
Pepin33 is offline   Reply With Quote
Old 09-03-2012, 02:04 PM   #11
jackie_w
Grand Sorcerer
jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.jackie_w ought to be getting tired of karma fortunes by now.
 
Posts: 6,212
Karma: 16534894
Join Date: Sep 2009
Location: UK
Device: Kobo: KA1, ClaraHD, Forma, Libra2, Clara2E. PocketBook: TouchHD3
I just tried my plugin again - as a normal user would use it.

When I Esc or Close-window-with-x-button, I get the same result as I do when I press the Cancel button of the QProgressDialog widget.

In my case it is copying images from calibre to a directory on a connected reader. The copying stops when any of the 3 actions is taken. The files already copied seem to be useable.

It is also apparent from the logging info I am collecting that dlg.wasCanceled() = True when tested by the calling program.
jackie_w is offline   Reply With Quote
Old 09-03-2012, 02:16 PM   #12
Pepin33
Zealot
Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.
 
Posts: 109
Karma: 419
Join Date: Aug 2012
Location: Spain
Device: Kindle Touch
Maybe the problem is that I don't have a "Cancel" button, then. I'm going to put one, and checking self.wasCanceled() to stop the process...

Last edited by Pepin33; 09-03-2012 at 02:19 PM.
Pepin33 is offline   Reply With Quote
Old 09-04-2012, 02:54 AM   #13
Pepin33
Zealot
Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.Pepin33 has a complete set of Star Wars action figures.
 
Posts: 109
Karma: 419
Join Date: Aug 2012
Location: Spain
Device: Kindle Touch
Right. I tried putting a "Cancel" button, and then I have a self.wasCanceled()=true when the progress dialog is closed by the user (pressing "Cancel", "Close" or "ESC" key).

The problem comes if you don't use a "Cancel" button. Then, the wasCanceled() function doesn't help. Then, how can you know that the window is closing to stop the process you're doing? Another question: Anybody knows how can I cancel the "ESC" signal at PyQt windows, to prevent the user can close the dialog this way?
Pepin33 is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Python help please AndyW1691 Library Management 3 02-08-2012 09:51 AM
python 2.X to 3.X migration? KevinH Calibre 7 02-13-2011 07:56 PM
What is python The Terminator General Discussions 20 01-21-2011 12:58 PM
Python 2.7 DiapDealer Calibre 4 12-17-2010 11:19 AM
Python 2.5 or 2.6? itimpi Calibre 5 01-19-2009 12:48 PM


All times are GMT -4. The time now is 06:31 AM.


MobileRead.com is a privately owned, operated and funded community.