728x90
반응형
이 글에서는 Qt를 사용해 다운로드 진행 상태를 표시하고 자동 설치 기능을 제공하는 다운로드 매니저를 구현하는 방법을 다룹니다. 이 프로젝트는 다운로드한 파일을 "installer" 디렉터리에 저장하고, 다운로드가 완료되면 자동으로 인스톨러를 실행합니다.
참고 코드 : QSimpleUpdater
프로젝트 소개
이 프로젝트는 GitHub Pages에 업로드된 **인스톨러 파일(installer.exe)**을 Qt 애플리케이션에서 다운로드하고, **프로그래스바(progress bar)**를 통해 진행 상태와 남은 시간을 UI로 보여줍니다.
사용자는 설정된 디렉터리에 다운로드된 파일을 자동으로 실행할 수 있습니다.
구현 목표
- 프로그래스바로 다운로드 진행 상태 표시
- 남은 시간 계산 및 표시
- 인스톨러 다운로드 후 자동 실행
- 사용자 정의 디렉터리에 파일 저장
1. 프로젝트 파일 구조
/project-root
│
├── main.cpp # 메인 프로그램 진입점
├── download_manager.cpp # 다운로드 및 설치 코드
├── download_manager.h # 다운로드 관련 헤더 파일
├── installer # 다운로드된 파일 저장 경로
└── installer_v1.0.0.exe # 다운로드될 인스톨러 파일 (예시)
2. 깃헙 페이지(GitHub Pages) 설정
이 프로젝트는 GitHub Pages를 통해 호스팅된 인스톨러를 다운로드합니다. 테스트를 위해서는 다음과 같은 설정이 필요합니다:
1.GitHub 저장소 생성:
- 공개 저장소를 만들고, **Settings > Pages**로 이동해 GitHub Pages를 활성화합니다.
2.인스톨러 파일 업로드:
- 다운로드할 인스톨러 파일(installer.exe)을 저장소의 루트 경로 또는 서브 디렉터리에 업로드합니다.
/v1.0.0/installer.exe
3.GitHub Pages 배포 완료 후 URL 확인:
- 인스톨러의 URL을 기억합니다. 예:
https://yourusername.github.io/yourrepository/v1.0.0/installer.exe
4.GitHub에 푸시(push):
- 파일 업로드 후 저장소에 푸시합니다.
3. 코드 작성 및 수정
📄 download_manager.h (헤더 파일)
#ifndef DOWNLOAD_MANAGER_H
#define DOWNLOAD_MANAGER_H
#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QProgressBar>
#include <QLabel>
#include <QString>
class Downloader : public QWidget {
Q_OBJECT
public:
explicit Downloader(QWidget *parent = nullptr);
~Downloader();
void startDownload(const QUrl &url);
void setFileName(const QString &file);
void setDownloadDir(const QString &downloadDir);
QString downloadDir() const;
private slots:
void updateProgress(qint64 received, qint64 total);
void finished();
void calculateTimeRemaining(qint64 received, qint64 total);
private:
QNetworkAccessManager *m_manager;
QNetworkReply *m_reply;
QString m_fileName;
QString m_downloadDir;
qint64 m_startTime;
QProgressBar *m_progressBar;
QLabel *m_timeLabel;
QLabel *m_downloadLabel;
void saveFile(qint64 received, qint64 total);
};
#endif // DOWNLOAD_MANAGER_H
📄 download_manager.cpp (다운로드 매니저 구현)
#include "download_manager.h"
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDesktopServices>
#include <QDateTime>
#include <QDir>
#include <QFile>
Downloader::Downloader(QWidget *parent)
: QWidget(parent), m_manager(new QNetworkAccessManager(this)), m_reply(nullptr) {
setWindowTitle(tr("Installer Download Manager"));
// UI 설정
m_progressBar = new QProgressBar(this);
m_timeLabel = new QLabel(tr("Time remaining: Unknown"), this);
m_downloadLabel = new QLabel(tr("Downloading updates..."), this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(m_downloadLabel);
layout->addWidget(m_progressBar);
layout->addWidget(m_timeLabel);
setLayout(layout);
// 디렉터리 생성
QDir dir("installer");
if (!dir.exists()) {
dir.mkpath(".");
}
m_downloadDir = dir.absolutePath();
}
Downloader::~Downloader() {
delete m_reply;
delete m_manager;
}
void Downloader::startDownload(const QUrl &url) {
m_progressBar->setValue(0);
m_downloadLabel->setText(tr("Downloading updates..."));
m_timeLabel->setText(tr("Time remaining: Unknown"));
QNetworkRequest request(url);
m_reply = m_manager->get(request);
m_startTime = QDateTime::currentDateTime().toSecsSinceEpoch();
connect(m_reply, &QNetworkReply::downloadProgress, this, &Downloader::updateProgress);
connect(m_reply, &QNetworkReply::finished, this, &Downloader::finished);
show();
}
void Downloader::setFileName(const QString &file) {
m_fileName = file.isEmpty() ? "installer_v1.0.0.exe" : file;
}
void Downloader::setDownloadDir(const QString &downloadDir) {
m_downloadDir = downloadDir;
}
QString Downloader::downloadDir() const {
return m_downloadDir;
}
void Downloader::updateProgress(qint64 received, qint64 total) {
if (total > 0) {
m_progressBar->setMaximum(100);
m_progressBar->setValue((received * 100) / total);
calculateTimeRemaining(received, total);
}
}
void Downloader::calculateTimeRemaining(qint64 received, qint64 total) {
uint elapsed = QDateTime::currentDateTime().toSecsSinceEpoch() - m_startTime;
if (elapsed > 0) {
qreal speed = received / elapsed;
qreal remainingTime = (total - received) / speed;
QString timeString;
if (remainingTime > 3600) {
timeString = tr("about %1 hours").arg(int(remainingTime / 3600));
} else if (remainingTime > 60) {
timeString = tr("about %1 minutes").arg(int(remainingTime / 60));
} else {
timeString = tr("%1 seconds").arg(int(remainingTime));
}
m_timeLabel->setText(tr("Time remaining: %1").arg(timeString));
}
}
void Downloader::saveFile(qint64 received, qint64 total) {
Q_UNUSED(received);
Q_UNUSED(total);
QFile file(m_downloadDir + "/" + m_fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Append)) {
file.write(m_reply->readAll());
file.close();
}
}
void Downloader::finished() {
if (m_reply->error() != QNetworkReply::NoError) {
QMessageBox::critical(this, tr("Error"), tr("Download failed!"));
return;
}
saveFile(0, 0);
m_reply->deleteLater();
QMessageBox::information(this, tr("Download Complete"), tr("Installer downloaded successfully!"));
// 인스톨러 실행
QDesktopServices::openUrl(QUrl::fromLocalFile(m_downloadDir + "/" + m_fileName));
close();
}
📄 main.cpp (메인 프로그램)
#include
#include "download_manager.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Downloader downloader;
downloader.setFileName("installer_v1.0.0.exe");
downloader.startDownload(QUrl("https://yourusername.github.io/yourrepository/v1.0.0/installer.exe"));
return app.exec();
}
4. 코드 수정 방법
1.다운로드 URL 변경:
- main.cpp에서 다운로드할 인스톨러 파일의 URL을 변경합니다:
downloader.startDownload(QUrl("https://yourusername.github.io/yourrepository/v1.0.0/installer.exe"));
2.파일 이름 변경:
- 다운로드된 파일의 이름을 설정합니다:
downloader.setFileName("installer_v1.0.0.exe");
3.저장 경로 변경:
- download_manager.cpp에서 저장할 디렉터리를 변경합니다:
QDir dir("your_custom_directory");
5. 마무리
이제 Qt로 다운로드 매니저를 구현하여, GitHub Pages에서 파일을 다운로드하고 진행 상태를 표시할 수 있습니다. 코드를 적절히 수정해 다른 파일이나 URL로도 쉽게 테스트할 수 있습니다.
추가 질문이 있거나 도움이 필요하면 언제든지 문의하세요
'임베디드 관련 카테고리 > Qt' 카테고리의 다른 글
Qt Installer 자동화 도구 구현하기: 디렉터리 구조 생성부터 압축까지 (1) | 2024.11.08 |
---|---|
Qt Creator를 활용한 자동 업데이트 설정: 구조와 계획 (3) | 2024.11.07 |
Qt Creator를 사용한 GitHub API 기반 버전 관리 모듈 분리 및 사용하기 (0) | 2024.10.29 |
Rock Paper Scissors Installer: 버전별 관리와 설치 프로그램 생성 가이드 (Windows CMD) (1) | 2024.10.28 |
GitHub Pages와 Qt Installer Framework를 이용해 온라인 설치 프로그램 만들기 (1) | 2024.10.25 |
댓글