tags:

views:

261

answers:

2

Often times when we're drawing a GUI, we want our GUI to update based on the data changing in our program. At the start of the program, let's say I've drawn my GUI based on my initial data. That data will be changing constantly, so how can I redraw my GUI constantly?

A: 

You could create a thread to update the GUI constantly, just pass to it references to the graphical widgets that need to be updated

Stb
That sounds plausible, could you show me a quick example possibly? PyQt threads did not really work out for me and I ended up just using QApplication.processEvents()
Chris
A: 

The best way that I have found to do this is to run your core program in a QTread and use signals to communicate with your gui. Here is an example where I update a progress dialog as my main program does some stuff.

Here is a code excerpt from a project that I was working on. The basic idea is that I am adding a number of files to a library object and updating the progress as the files are added.

The action is started by the Library class. The tread that does the actual work is in the AddFilesThread.

Let me know if this is helpful. If you need I can try to put together a working example instead of a code excerpt.



If you want to see the full code that I used go here: hystrix_library.py. The diaglog class that I used is in that file. I can't say that this is necessarily the best way to do things, but it works well and is fairly easy to read.

class Library(QtCore.QObject):
    """
    This class is used to store information on the libraries.
    """
    def __init__(self):
        QtCore.QObject.__init__(self)

    def importUrls(self, url_list):

        # Create a progress dialog
        self.ui_progress = AddUrlsProgressDialog()
        self.ui_progress.show()
        self.ui_progress.raise_()

        # Create the add files thread object.
        self.add_files_thread = AddFilesThread()

        # Connect the thread to the dialog.
        self.connect(self.add_files_thread
                     ,QtCore.SIGNAL('updateDialog')
                     ,self.ui_progress.setDialog)

        self.connect(self.add_files_thread
                     ,QtCore.SIGNAL('updateValue')
                     ,self.ui_progress.setValue)

        self.connect(self.add_files_thread
                     ,QtCore.SIGNAL('finished')
                     ,self.ui_progress.setFinished)

        self.connect(self.add_files_thread
                     ,QtCore.SIGNAL('canceled')
                     ,self.ui_progress.closeNow)

        # Connect the dialog to the thread
        self.connect(self.ui_progress
                     ,QtCore.SIGNAL('cancel')
                     ,self.add_files_thread.cancelRequest)        

        # Start the thread
        self.add_files_thread.start()




class AddFilesThread(QtCore.QThread):

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

        self.cancel_request = False

    def __del__(self):
        self.wait()

    def run(self):
        try:
            self.main()
        except:
            print 'AddFilesThread broke yo.'
            self.cancelNow(force=True)
            traceback.print_exc()

    def main(self):
        num_added = 0
        for local_path in self.path_list:
            # First Setup the dialog
            status_label = 'Finding files to add . . .'
            dialog_update = (status_label, (0,0), 0)
            self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)

            # Do a recursive search.
            all_files = hystrix_file.getFiles()
            num_files = len(all_files)

            if self.cancelNow():
                return

            status_label = '%d files found.\nExtracting tags . . .' %(num_files)
            dialog_update = (status_label, (0,num_files), 0)
            self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)

            num_added = 0
            for index, filename in enumerate(all_files):
                try:
                    metadata = hystrix_tags.getMetadata(filename)
                    # Here I would add the metadata to my library.
                except:
                    traceback.print_exc()
                    print('Could not extract Metadata from file.')
                    continue

                # This should be sent to a progress widget
                if index % 1 == 0:
                    self.emit(QtCore.SIGNAL('updateValue'), index)

                # Check if a cancel signal has been recieved
                if self.cancelNow():
                    return

        status_label = 'Finished. Added %d files.' %(num_added)
        dialog_update = ( status_label, (0,num_added), num_added)
        self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)

        self.emit(QtCore.SIGNAL('finished'))

    def cancelRequest(self):
        self.cancel_request = True

    def cancelNow(self, force=False):
        if self.cancel_request or force:
            self.emit(QtCore.SIGNAL('canceled'))
            return True
        else:
            return False
amicitas