如何开始“绘图循环”在 PyQt 中?

发布于 2024-08-20 20:39:22 字数 103 浏览 2 评论 0原文

很多时候,当我们绘制 GUI 时,我们希望 GUI 根据程序中的数据变化进行更新。在程序开始时,假设我已经根据初始数据绘制了 GUI。这些数据会不断变化,那么我怎样才能不断地重绘我的GUI呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

提赋 2024-08-27 20:39:22

我发现做到这一点的最好方法是在 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

The best way that I have found to do this is to run your core program in a QThread 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
九局 2024-08-27 20:39:22

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文