Using QtCore Mutliple Threads to keep QtDialog GUI responsive during Processing Tasks

I am just in the phase of familiarizing with Ruby, hence my apologies beforehand, if some questions may seem naive.

I am dealing with larger files to be loaded into KLayout, which can take some time occasionally. For the File Input I created a Qt Dialog GUI by means of Qt designer, which works nicely in Ruby as the Dialog Elements and their properties can be accessed conveniently. In order to keep the Qt Dialog GUI responsive during loading times and to give the user some feedback about the loading progress, I implemented some progress bars in that Dialog GUI. In some Qt releated forums, I've read that a common way to update the Dialog's GUI during processing times is to use QtCore to setup a worker thread and another thread for updating the Dialog's GUI. If any one has done something like this before in a Ruby script, some help and perhaps an example code snippet would be highly appreciated.

Kind Regards
Thomas

Comments

  • It's not that easy ...

    Qt isn't thread safe and you can only access the Ui objects from the main thread. You can pass signals acress thread boundaries, but only in an asynchronous fashion. Qt (and other frameworks) and threaded applications is a complex topic about which many books have been written, and KLayout adds to this complexity as the database isn't fully thread-safe either.

    Bottom line: don't try threads.

    Instead the classic way of keeping an application responsive is to occasionally call "Application#process_events", i.e.

    RBA::Application::instance.process_events
    

    This will make the application process all mouse and repaint events and keeps it responsive. Don't call it too often as it may slow down your reader, but if you're reading lines from a text file, calling process_events every 1000 lines or so may be a good idea.

    There is a pitfall though: it will block user events, so you cannot click some "Cancel" button. You can basically use "QApplication#processEvents" as well which gives you more control - specifically it lets you handle mouse and input events. But beware: this also allows the user to close the window while loading, so in order to prevent this you need to make sure that your dialog is modal (otherwise the user can interact with the rest of the application) and all "forbidden" features are disabled during loading.

    The stream readers basically do the same and only leave the "Cancel" button enabled in the central window's progress bar.

    Matthias

  • Dear Matthias,

    many thanks for the feedback. Your recommendation worked nicely. I ended up calling the app.process_events method every 10% of the loading-progress.

    if progress % 10 == 0

    progressBar_3.value = progress

    app.process_events

    end

    The dialog is kept modal with only the Cancel-Button being enabled.

    Kind Regards
    Thomas

Sign In or Register to comment.