简体   繁体   中英

pyqt: long process in file open dialog

I have little experience in GUI programming but I'm writing a GUI application with PyQt. With this application, user can open a binary file and do some editing with it.

When the file is opened, I do some processing that takes a while (~15s). So when the user pick the file and press the "Open" button in the file open dialog, the GUI is frozen. What's the best way to achieve a better user experience?

Thanks

Load in the background showing the progress via a Gauge in the statusbar.

To to this, you can initiate the loading using QThread. Your thread class can look as follows (assuming parent will have an attribute progress ):

QtFileLoader(QtCore.QThread):
    def __init__(self,parent=None, filepath=None):
        QtCore.QThread.__init__(self,parent)
        self.data = None
        self.filepath = filepath

    def run(self):
        """ load data in parts and update the progess par """
        chunksize = 1000
        filesize = ... # TODO: get length of file
        n_parts = int(filesize/chunksize) + 1
        with open(self.filepath, 'rb') as f:
            for i in range(n_parts):
                self.data += f.read(chunksize)
                self.parent.progress = i 

The question whether to use QThread or trheading.Thread is discussed here

edit (according to hint of @Nathan): On the parent , a timerfunction should check, say each 100ms, the value of self.parent.progress and set the progressbar accordingly. This way, the progressbar is set from within the main thread of the GUI.

You need to periodically ask the application to process events pending on the event queue. You do so by calling the processEvents() method of the QApplication instance. If you can intersperse your calculations with calls to processEvents(), the GUI, and progress bars, will update themselves. Note that this is not the same as making the GUI responsive.

To make the GUI responsive while performing your load, you will need to split the load operation into a background thread. You cannot perform GUI operations from the background thread, though the background thread can emit signals that cross thread boundaries. Here is an article on multi-threaded PyQt programming.

You are looking for some method to do the job in a different thread that that of the GUI mainloop.
You could check here to start

Major gui frameworks as wxpython and pyQt have methods to run long running applications without freezing the gui. Personally I prefer to use directly the python thread module

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM