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

在 PyQt 中实现一个“绘图循环”可以使用 定时器QTimer),让应用程序在指定的时间间隔内反复触发一个绘图函数。这种方法对于需要持续更新绘图(例如动画效果)的情况特别有用。

在这里插入图片描述

1、问题背景

在GUI编程中,我们经常需要让GUI根据程序中不断变化的数据进行更新。在程序启动时,我们可能已经根据初始数据绘制了GUI。但是,这些数据会不断变化,因此我们需要一种方法来不断地重新绘制GUI。

2、解决方案

一种有效的方法是将核心程序运行在一个QThread中,并使用信号与GUI进行通信。下面是一个示例,演示如何使用QThread和信号在主程序执行某些操作时更新进度对话框。

class Library(QtCore.QObject):
    def __init__(self):
        QtCore.QObject.__init__(self)

    def importUrls(self, url_list):
        # 创建一个进度对话框
        self.ui_progress = AddUrlsProgressDialog()
        self.ui_progress.show()
        self.ui_progress.raise_()

        # 创建添加文件线程对象
        self.add_files_thread = AddFilesThread()

        # 连接线程和对话框
        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)

        # 连接对话框和线程
        self.connect(self.ui_progress, QtCore.SIGNAL('cancel'), self.add_files_thread.cancelRequest)

        # 启动线程
        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:
            # 首先设置对话框
            status_label = 'Finding files to add . . .'
            dialog_update = (status_label, (0, 0), 0)
            self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)

            # 执行递归搜索
            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)
                    # 在这里,我将元数据添加到我的库中
                except:
                    traceback.print_exc()
                    print('Could not extract Metadata from file.')
                    continue

                # 应该将其发送到进度小部件
                if index % 1 == 0:
                    self.emit(QtCore.SIGNAL('updateValue'), index)

                # 检查是否收到取消信号
                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

在主程序中,我们可以使用以下代码来启动绘图循环:

# 创建一个 Library 对象
library = Library()

# 将 URL 列表传递给 Library 对象
library.importUrls(url_list)

最后小结

  • 在 PyQt 中,使用 QTimer 是实现绘图循环的主要方法。
  • 通过定期调用 update() 方法,触发 paintEvent,从而不断地重新绘制内容。
  • 这种方法非常适合实现简单的动画效果,但对于复杂动画或游戏应用,建议使用更加专业的图形库或 PyQt 的更高级功能。

这就是在 PyQt 中实现绘图循环的基本方法,希望对你有所帮助!

猜你喜欢

转载自blog.csdn.net/weixin_44617651/article/details/143574604