⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 updaterclient.cpp

📁 QT写的自动更新程序 自认为不错 请大家参考
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	QTreeView* pviewPacks = ui.Packs;
	QAbstractItemModel* pItems = pviewPacks->model();
	//QMap<int, QVariant> find = pItems->itemData(qindex);
	
	const QModelIndex& temindex = pItems->index(qindex.row(), 0);
	QMap<int, QVariant> find = pItems->itemData(temindex);
	
	if (!SIZE(find))
		return;
	Q_ASSERT(SIZE(find));
	
	QString seletedstr = find[0].toString();
	TMapReadyPacks::iterator findpack = mapReadyPacks.find(seletedstr);
	if (findpack == mapReadyPacks.end())
		return;

	const IUpdatePack* pPack = findpack->second;
	//显示补丁信息
	QTextBrowser* ptextPackinfo = ui.packInfo;
	ptextPackinfo->setHtml(pPack->info);
}

void UpdaterClient::downloadPacks()
{
	if (!SIZE(mapReadyPacks)) return;

	//更新checkbox状态来决定是否需要下载该补丁
	//遍历所有的行
	bool existneeddownload = false;//是否存在需要下载的项目
	for (int row=0; row<pStdItemModel->rowCount(); row++)
	{
		//pStdItemModel->removeRows(row, 1);
		QStandardItem* pitem = pStdItemModel->item(row);

		bool checked;
		if (pitem->isCheckable())
		{
			//可选补丁
			checked = pitem->checkState() == Qt::Checked;
		}
		else//必选补丁
			checked = true;

		QString seletedstr = pitem->text();
		TMapReadyPacks::iterator findpack = mapReadyPacks.find(seletedstr);
		if (findpack == mapReadyPacks.end())
			return;

		IUpdatePack* pPack = findpack->second;
		pPack->needdownload = checked;

		if (!checked)
			filecount++;//如果属于未选中的,则改变下载基数

		existneeddownload |= checked;
	}
	if (!existneeddownload)
		return;//不存在需要下载的项目

	pubfunc::release(opeFtp);

	//
	iterInstallingPack = mapReadyPacks.begin();//第一个补丁

	//建立环境
	opeFtp = new QFtp();
	opeFtp->connectToHost(getClientCenter()->ftpAddress);

	//绑定信号
	connect(opeFtp, SIGNAL(commandFinished (int, bool)),
		this, SLOT(on_ftpCommandFinished(int, bool)));
	connect(opeFtp, SIGNAL(dataTransferProgress(qint64, qint64)),
		this, SLOT(on_ftpDataTransferProgress(qint64, qint64)));

	//登陆服务器
	opeFtp->login("Client", "Client");
}

void UpdaterClient::installPacks()
{
	if (!SIZE(mapReadyPacks)) return;

	QLabel* plabelStatus = ui.statusLabel;
	plabelStatus->setText(tr("Installing..."));
	plabelStatus->setVisible(true);

	//新建一安装线程
	pubfunc::release(pPacksInstallThread);
	pPacksInstallThread = new PacksInstallThread();

	//绑定信号量
	connect(pPacksInstallThread, SIGNAL(installed()),
		this, SLOT(on_packsInstalled()));
	connect(pPacksInstallThread, SIGNAL(progressStep(QString, int, int)),
		this, SLOT(on_packInstallProgress(QString, int, int)));
	connect(pPacksInstallThread, SIGNAL(selfUpdatePack()),
		this, SLOT(on_threadSelfUpdate()));
	connect(pPacksInstallThread, SIGNAL(appMustBClosed(QString)),
		this, SLOT(on_thread_appMustBClosed(QString)));

	pPacksInstallThread->installAllPacks(mapReadyPacks);
}

void UpdaterClient::on_thread_appMustBClosed(QString appname)
{
	QMessageBox::warning(0, tr("warning"), tr("please close the app ") + appname);
	pPacksInstallThread->appshut = true;
}

void UpdaterClient::on_threadSelfUpdate()
{
	pPacksInstallThread->quit();
	this->close();
	QApplication::quit();
}

//下载更新的按钮被按动
//分为两种模式,1为下载,2为安装
void UpdaterClient::on_btndownloadall_clicked()
{	
	switch (btnMode)
	{
	case BM_DownLoad:
		{//下载所有的更新
			downloadPacks();
			break;
		}
		break;
	case BM_Install:
		{//安装所有的更新
			installPacks();
			break;
		}
		break;
	case BM_Complete:
		{
			//退出程序
			QApplication::exit();
		}
		break;
	}
}

void UpdaterClient::on_packsInstalled()
{
	//全部安装完成
	QPushButton* pbtnDownAll = ui.btndownloadall;
	pbtnDownAll->setText(tr("Quit"));
	btnMode = BM_Complete;

	//隐藏掉进度显示
	QLabel* plabelStatus = ui.statusLabel;
	plabelStatus->setVisible(false);

	QTextBrowser* qtextPackInfo = ui.packInfo;
	qtextPackInfo->setHtml(tr("Install Finish"));

	wTrayWindow::showTrayMessage(tr("info"), tr("Install Finish"));

	//全部安装结束,恢复按钮状态
	ui.btndownloadall->setDisabled(false);
}

void UpdaterClient::on_packInstallProgress(QString name, int filescount, int fileindex)
{
	QLabel* plabelStatus = ui.statusLabel;
	plabelStatus->setText(QString(tr("Installing...")) + QString(" %1").arg(name));

	QProgressBar* pProgressBar = ui.progressBarAllDownload;
	pProgressBar->setRange(0, filescount);
	pProgressBar->setValue(fileindex);
}

void UpdaterClient::on_ftpDataTransferProgress(qint64 done, qint64 total)
{
	QProgressBar* pdownProgress = ui.progressBarAllDownload;
	pdownProgress->setRange(0, total);
	pdownProgress->setValue(done);
}

void UpdaterClient::on_ftpCommandFinished(int id, bool error)
{
	//连接前预判断
	switch (opeFtp->currentCommand())
	{
	case QFtp::ConnectToHost:
	case QFtp::Login:
		{
			if (error)
			{
				getClientCenter()->logs.push_back(opeFtp->errorString());
				getClientCenter()->pTrayIcon->setIcon(QIcon(":/lost.png"));
				return;
			}
		}
		break;
	case QFtp::Get:
		{
			//已经下载完成
			if (!error)
				opeFile->close();
			else
				opeFile->remove();

			pubfunc::release(opeFile);

			filecount++;
			if (filecount == SIZE(mapReadyPacks))
			{
				//关闭ftp链接
				opeFtp->close();

				//所有文件已经下载好了
				afterAllPacksDownloaded();
			}
			else
				donwloadNextPack();
		}
	}

	switch (opeFtp->currentCommand())
	{
	case QFtp::Login:
		{
			if (opeFtp->state() == QFtp::LoggedIn)
			{
				QPushButton* pbtnDownAll = ui.btndownloadall;
				pbtnDownAll->setEnabled(false);

				donwloadNextPack();

				//登陆成功,可以开始下载文件
// 				TMapReadyPacks::iterator iterReadyPack = mapReadyPacks.begin();
// 				while(iterReadyPack != mapReadyPacks.end())
// 				{
// 					const IUpdatePack* pPack = iterReadyPack->second;
// 
// 					
// 					++iterReadyPack;
// 				}
			}
		}
		break;
	}
}

//下载下一个更新
void UpdaterClient::donwloadNextPack()
{
	if (iterInstallingPack == mapReadyPacks.end())
		return;

	IUpdatePack* pPack = iterInstallingPack->second;
	while (!pPack->needdownload && iterInstallingPack != mapReadyPacks.end())
	{
		iterInstallingPack++;
		pPack = iterInstallingPack->second;
	}

	if (!pPack->needdownload)
		return;
	//找到一个需要下载的

	//建立对应软件更新的目录
	QDir dir(getClientCenter()->localRecipesDir);
	if ( !dir.exists(QString("%1").arg(pPack->softname)))
		dir.mkdir(QString("%1").arg(pPack->softname));

	//如果当前文件下已经存在该文件,则比对md5码决定是否需要下载
	QString localFileName = getClientCenter()->localRecipesDir + QString("/%1/%2").arg(pPack->softname).arg(pPack->packName);
	QFileInfo localFileInfo(localFileName);
	bool needDownload = true;//是否需要下载该文件
	if (localFileInfo.exists())
	{
		//如果本地已存在同名文件,则需要匹配md5编码
		QString localMd5 = wFileFunc::calcFileMd5(localFileName);
		if ( localMd5 == pPack->md5 )
		{
			//如果md5匹配则不需要下载该文件
			needDownload = false;
			//计数器自增
			filecount++;
			if (filecount == SIZE(mapReadyPacks))
			{
				//关闭ftp链接
				opeFtp->close();
				//所有文件已经下载好了
				afterAllPacksDownloaded();
			}
			else
			{
				iterInstallingPack ++;
				donwloadNextPack();
				return;
			}
		}
		else
		{
			//! 如果不匹配
			//! 为了支持断点续传,则不移除同名文件
			//QFile::remove(localFileName);
		}
	}

	//和需要下载的位与
	needDownload &= pPack->needdownload;

	if (needDownload)
	{
		QLabel* plabelStatus = ui.statusLabel;
		plabelStatus->setText(QString(tr("downloading ") + pPack->name));
		plabelStatus->setVisible(true);

		//下载更新的文件
		wFtpFunc::downloadFileEx(opeFtp, opeFile,
			QString("/%1/%2").arg(pPack->softname).arg(pPack->packName),
			getClientCenter()->localRecipesDir);
	}

	iterInstallingPack ++;
}

//所有文件下载完毕
void UpdaterClient::afterAllPacksDownloaded()
{
	QLabel* plabelStatus = ui.statusLabel;

	//下载完成,隐藏信息显示
	plabelStatus->setVisible(false);
	plabelStatus->setText(tr("Installing..."));

	//改变按钮文字为安装更新
	QPushButton* pbtnDownAll = ui.btndownloadall;
	pbtnDownAll->setText(tr("Install"));
	pbtnDownAll->setEnabled(true);
	btnMode = BM_Install;

	//跟新信息显示
	QTextBrowser* qtextPackInfo = ui.packInfo;
	qtextPackInfo->setHtml(tr("Download Finished"));

	wTrayWindow::showTrayMessage(tr("info"), tr("Download Finished"));

	//
	QProgressBar* pDownloadProgress = ui.progressBarAllDownload;
	pDownloadProgress->setRange(0, 100);
	pDownloadProgress->setValue(100);

	//自动安装
	if (getCConfig()->getValue("AutoInstall").toBool())
	{
		//如果是自动安装,则禁用按钮
		ui.btndownloadall->setDisabled(true);

		installPacks();
	}

}

void UpdaterClient::showLogs()
{
	std::list<QString>& logs = getClientCenter()->logs;
	if (SIZE(logs))
	{
		//存在没有看过的日志
		QString logstr = pubfunc::combine<QString, std::list<QString> >(logs, "\n");
		//logs.clear();
		QMessageBox::warning(this, tr("warning"), logstr);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -