如何在PyQt中启动“绘图循环”?

时间:2010-02-03 15:21:21

标签: python pyqt

通常,当我们绘制GUI时,我们希望GUI根据程序中的数据更改进行更新。在程序开始时,假设我根据我的初始数据绘制了GUI。这些数据会不断变化,所以如何不断重绘我的GUI?

2 个答案:

答案 0 :(得分:1)

我发现这样做的最好方法是在QThread中运行核心程序并使用信号与你的gui进行通信。这是一个我更新进度对话框的例子,因为我的主程序做了一些事情。

以下是我正在处理的项目的代码摘录。基本思想是我将一些文件添加到库对象,并在添加文件时更新进度。

该操作由Library类启动。完成实际工作的步骤是AddFilesThread

如果这有用,请告诉我。如果您需要,我可以尝试将一个工作示例放在一起,而不是代码摘录。



如果您想查看我使用的完整代码,请访问:hystrix_library.py。我使用的diaglog类在该文件中。我不能说这必然是最好的做事方式,但它运作良好且相当容易阅读。

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

答案 1 :(得分:0)

您可以创建一个线程来不断更新GUI,只需传递给需要更新的图形小部件的引用