首页 > 解决方案 > 我想在pyqt5中实现下载git repo的进度条

问题描述

如何制作进度条以克隆 git 存储库pyqt5

git.Repo.clone_from('https://github.com/addddd123/Osdag', '_new_update')

标签: python-3.xpyqt5

解决方案


您必须在另一个线程中执行任务,连接到回调并通过信号发送进度信息:

import threading
import sys
from dataclasses import dataclass, field
from typing import List, Optional, Any, Mapping, Dict

from PyQt5 import QtCore, QtWidgets

import git


class GitReply(QtCore.QObject):
    pass


@dataclass
class GitCloneReply(GitReply):
    progress_changed = QtCore.pyqtSignal(int)
    started = QtCore.pyqtSignal()
    finished = QtCore.pyqtSignal()

    url: str
    path: str
    env: Optional[Mapping[str, Any]] = None
    multi_options: Optional[List[str]] = None
    kwargs: Dict[str, Any] = field(default_factory=dict)

    def __post_init__(self):
        super().__init__()

    def start(self):
        threading.Thread(target=self._execute, daemon=True).start()

    def _execute(self):
        self.started.emit()
        repo = git.Repo.clone_from(
            self.url,
            self.path,
            self.callback,
            self.env,
            self.multi_options,
            **self.kwargs
        )
        self.finished.emit()

    def callback(self, op_code, cur_count, max_count=None, message=""):
        self.progress_changed.emit(int((cur_count / max_count) * 100))


@dataclass
class RepoManager(QtCore.QObject):
    _replies: List[GitReply] = field(init=False, default_factory=list)

    def __post_init__(self):
        super().__init__()

    def clone_from(self, url, path, env=None, multi_options=None, **kwargs):
        reply = GitCloneReply(url, path, env, multi_options, kwargs)
        reply.finished.connect(self.handle_finished)
        reply.start()
        self._replies.append(reply)
        return reply

    def handle_finished(self):
        reply = self.sender()
        if reply in self._replies:
            self._replies.remove(reply)


def main():
    app = QtWidgets.QApplication(sys.argv)

    progressbar = QtWidgets.QProgressBar()
    progressbar.show()

    manager = RepoManager()
    reply = manager.clone_from("https://github.com/addddd123/Osdag", "_new_update")
    reply.progress_changed.connect(progressbar.setValue)

    ret = app.exec_()
    sys.exit(ret)


if __name__ == "__main__":
    main()
```

推荐阅读