mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-09-26 13:02:20 +08:00
修复 加载应用程序信息时随机崩溃
这个问题就是因为在异步操作时直接修改GUI,导致事件发生时GUI与异步加载线程不同步导致程序崩溃。将所有加载操作已移至 SpkAppInfoLoaderThread,在其需要操作GUI时阻塞该工作线程并发射信号让主线程操作GUI,以解决该问题。
This commit is contained in:
parent
1b56d3ad52
commit
367c8d857c
@ -18,7 +18,6 @@ image_show::image_show(QWidget *parent) : QWidget(parent)
|
|||||||
|
|
||||||
void image_show::setImage(QPixmap image)
|
void image_show::setImage(QPixmap image)
|
||||||
{
|
{
|
||||||
|
|
||||||
QImage screen0;
|
QImage screen0;
|
||||||
screen0=image.toImage();
|
screen0=image.toImage();
|
||||||
// QPainter painter(&screen0);
|
// QPainter painter(&screen0);
|
||||||
|
@ -33,14 +33,16 @@ SOURCES += main.cpp\
|
|||||||
downloadlist.cpp \
|
downloadlist.cpp \
|
||||||
image_show.cpp \
|
image_show.cpp \
|
||||||
big_image.cpp \
|
big_image.cpp \
|
||||||
progressload.cpp
|
progressload.cpp \
|
||||||
|
workerthreads.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
widget.h \
|
widget.h \
|
||||||
downloadlist.h \
|
downloadlist.h \
|
||||||
image_show.h \
|
image_show.h \
|
||||||
big_image.h \
|
big_image.h \
|
||||||
progressload.h
|
progressload.h \
|
||||||
|
workerthreads.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
287
widget.cpp
287
widget.cpp
@ -57,6 +57,13 @@ Widget::Widget(DBlurEffectWidget *parent) :
|
|||||||
connect(ui->menu_download,&DPushButton::clicked,[=](){Widget::chooseLeftMenu(13);});
|
connect(ui->menu_download,&DPushButton::clicked,[=](){Widget::chooseLeftMenu(13);});
|
||||||
// connect((ui->titlebar))
|
// connect((ui->titlebar))
|
||||||
|
|
||||||
|
connect(&appinfoLoadThread, SIGNAL(requestResetUi()), this, SLOT(sltAppinfoResetUi()), Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::requestSetTags, this, &Widget::sltAppinfoTags, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::requestSetAppInformation, this, &Widget::sltAppinfoDetails, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishedIconLoad, this, &Widget::sltAppinfoIcon, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishedScreenshotLoad, this, &Widget::sltAppinfoScreenshot, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishAllLoading, this, &Widget::sltAppinfoFinish, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
|
||||||
// 搜索事件
|
// 搜索事件
|
||||||
connect(searchEdit,&DSearchEdit::editingFinished,this,[=](){
|
connect(searchEdit,&DSearchEdit::editingFinished,this,[=](){
|
||||||
QString searchtext=searchEdit->text();
|
QString searchtext=searchEdit->text();
|
||||||
@ -126,6 +133,9 @@ void Widget::initUI()
|
|||||||
ui->icon->setPixmap(QIcon::fromTheme("spark-store").pixmap(36,36));
|
ui->icon->setPixmap(QIcon::fromTheme("spark-store").pixmap(36,36));
|
||||||
ui->titlebar->setFixedHeight(50);
|
ui->titlebar->setFixedHeight(50);
|
||||||
|
|
||||||
|
label_screen << ui->screen_0 << ui->screen_1 << ui->screen_2 << ui->screen_3 << ui->screen_4;
|
||||||
|
|
||||||
|
|
||||||
// 初始化分界线
|
// 初始化分界线
|
||||||
QGraphicsOpacityEffect *opacityEffect_1=new QGraphicsOpacityEffect;
|
QGraphicsOpacityEffect *opacityEffect_1=new QGraphicsOpacityEffect;
|
||||||
opacityEffect_1->setOpacity(0.1);
|
opacityEffect_1->setOpacity(0.1);
|
||||||
@ -201,9 +211,9 @@ void Widget::initConfig()
|
|||||||
QSettings readConfig(QDir::homePath()+"/.config/spark-store/config.ini",QSettings::IniFormat);
|
QSettings readConfig(QDir::homePath()+"/.config/spark-store/config.ini",QSettings::IniFormat);
|
||||||
if(readConfig.value("server/choose").toString()!=""){
|
if(readConfig.value("server/choose").toString()!=""){
|
||||||
ui->comboBox_server->setCurrentText(readConfig.value("server/choose").toString());
|
ui->comboBox_server->setCurrentText(readConfig.value("server/choose").toString());
|
||||||
serverUrl=readConfig.value("server/choose").toString();
|
appinfoLoadThread.setServer(serverUrl=readConfig.value("server/choose").toString());
|
||||||
}else {
|
}else {
|
||||||
serverUrl="http://sucdn.jerrywang.top/"; // 默认URL
|
appinfoLoadThread.setServer(serverUrl="http://sucdn.jerrywang.top/"); // 默认URL
|
||||||
}
|
}
|
||||||
configCanSave=true; // 防止触发保存配置信号
|
configCanSave=true; // 防止触发保存配置信号
|
||||||
menuUrl[0]=serverUrl + "store/#/";
|
menuUrl[0]=serverUrl + "store/#/";
|
||||||
@ -223,13 +233,13 @@ void Widget::initConfig()
|
|||||||
|
|
||||||
|
|
||||||
//web控件初始化
|
//web控件初始化
|
||||||
// ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); //用来激活接受linkClicked信号
|
// ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); //用来激活接受linkClicked信号
|
||||||
// ui->webView->page()->settings()->setAttribute(QWebSettings::JavascriptEnabled,true);
|
// ui->webView->page()->settings()->setAttribute(QWebSettings::JavascriptEnabled,true);
|
||||||
ui->webfoot->hide();
|
ui->webfoot->hide();
|
||||||
|
|
||||||
//初始化首页
|
//初始化首页
|
||||||
ui->webEngineView->setUrl(menuUrl[0]);
|
ui->webEngineView->setUrl(menuUrl[0]);
|
||||||
// ui->webEngineView->setUrl(menuUrl[1]);
|
// ui->webEngineView->setUrl(menuUrl[1]);
|
||||||
|
|
||||||
//给下载列表赋值到数组,方便调用
|
//给下载列表赋值到数组,方便调用
|
||||||
for (int i =0; i<LIST_MAX;i++){
|
for (int i =0; i<LIST_MAX;i++){
|
||||||
@ -261,7 +271,7 @@ void Widget::setTheme(bool isDark,QColor color)
|
|||||||
ui->btn_openDir->setStyleSheet("color:#8B91A1;background-color:#2E2F30;border:0px");
|
ui->btn_openDir->setStyleSheet("color:#8B91A1;background-color:#2E2F30;border:0px");
|
||||||
ui->webfoot->setStyleSheet("background-color:#252525");
|
ui->webfoot->setStyleSheet("background-color:#252525");
|
||||||
ui->label->setStyleSheet("background-color:#252525");
|
ui->label->setStyleSheet("background-color:#252525");
|
||||||
// ui->scrollArea->setStyleSheet("background-color:#252525");
|
// ui->scrollArea->setStyleSheet("background-color:#252525");
|
||||||
ui->label_show->setStyleSheet("background-color:#252525");
|
ui->label_show->setStyleSheet("background-color:#252525");
|
||||||
ui->pushButton_return->setIcon(QIcon(":/icons/icons/category_active_dark.svg"));
|
ui->pushButton_return->setIcon(QIcon(":/icons/icons/category_active_dark.svg"));
|
||||||
ui->pushButton_refresh->setIcon(QIcon(":/icons/icons/refresh-page-dark.svg"));
|
ui->pushButton_refresh->setIcon(QIcon(":/icons/icons/refresh-page-dark.svg"));
|
||||||
@ -272,7 +282,7 @@ void Widget::setTheme(bool isDark,QColor color)
|
|||||||
ui->webfoot->setStyleSheet("background-color:#FFFFFF");
|
ui->webfoot->setStyleSheet("background-color:#FFFFFF");
|
||||||
ui->btn_openDir->setStyleSheet("color:#505050;background-color:#FBFBFB;border:0px");
|
ui->btn_openDir->setStyleSheet("color:#505050;background-color:#FBFBFB;border:0px");
|
||||||
ui->label->setStyleSheet("background-color:#FFFFFF");
|
ui->label->setStyleSheet("background-color:#FFFFFF");
|
||||||
// ui->scrollArea->setStyleSheet("background-color:#F8F8F8");
|
// ui->scrollArea->setStyleSheet("background-color:#F8F8F8");
|
||||||
ui->label_show->setStyleSheet("background-color:#F8F8F8");
|
ui->label_show->setStyleSheet("background-color:#F8F8F8");
|
||||||
ui->pushButton_return->setIcon(QIcon(":/icons/icons/category_active.svg"));
|
ui->pushButton_return->setIcon(QIcon(":/icons/icons/category_active.svg"));
|
||||||
ui->pushButton_refresh->setIcon(QIcon(":/icons/icons/refresh-page.svg"));
|
ui->pushButton_refresh->setIcon(QIcon(":/icons/icons/refresh-page.svg"));
|
||||||
@ -288,23 +298,23 @@ void Widget::setTheme(bool isDark,QColor color)
|
|||||||
|
|
||||||
DTitlebar* Widget::getTitlebar()
|
DTitlebar* Widget::getTitlebar()
|
||||||
{
|
{
|
||||||
return ui->titlebar;
|
return ui->titlebar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::sendNotification(const QString &message, const int msTimeout, const QString &icon)
|
void Widget::sendNotification(const QString &message, const int msTimeout, const QString &icon)
|
||||||
{
|
{
|
||||||
system((QString("notify-send --icon=%1 --expire-time=%2 --app-name=").arg(icon).arg(msTimeout) +
|
system((QString("notify-send --icon=%1 --expire-time=%2 --app-name=").arg(icon).arg(msTimeout) +
|
||||||
tr("Spark\\ Store") +
|
tr("Spark\\ Store") +
|
||||||
" '" + message + "'"
|
" '" + message + "'"
|
||||||
).toUtf8());
|
).toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::sendNotification(const char *message, const int msTimeout, const QString &icon)
|
void Widget::sendNotification(const char *message, const int msTimeout, const QString &icon)
|
||||||
{
|
{
|
||||||
system((QString("notify-send --icon=%1 --expire-time=%2 --app-name=").arg(icon).arg(msTimeout) +
|
system((QString("notify-send --icon=%1 --expire-time=%2 --app-name=").arg(icon).arg(msTimeout) +
|
||||||
tr("Spark\\ Store") +
|
tr("Spark\\ Store") +
|
||||||
" '" + message + "'"
|
" '" + message + "'"
|
||||||
).toUtf8());
|
).toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateUI()
|
void Widget::updateUI()
|
||||||
@ -477,7 +487,7 @@ int Widget::loadappinfo(QUrl arg1)
|
|||||||
get_json.waitForFinished();
|
get_json.waitForFinished();
|
||||||
if(get_json.exitCode())
|
if(get_json.exitCode())
|
||||||
{
|
{
|
||||||
sendNotification(tr("Failed to download app info. Please check internet connection."));
|
sendNotification(tr("Failed to download app info. Please check internet connection."));
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile app_json("app.json");
|
QFile app_json("app.json");
|
||||||
@ -560,25 +570,21 @@ int Widget::loadappinfo(QUrl arg1)
|
|||||||
get_json.start("curl -o icon.png "+urladdress+"icon.png");
|
get_json.start("curl -o icon.png "+urladdress+"icon.png");
|
||||||
get_json.waitForFinished();
|
get_json.waitForFinished();
|
||||||
if(!get_json.exitCode()) {
|
if(!get_json.exitCode()) {
|
||||||
QPixmap appicon(QString::fromUtf8(TMP_PATH)+"/icon.png");
|
QPixmap appicon(QString::fromUtf8(TMP_PATH)+"/icon.png");
|
||||||
ui->label_appicon->setPixmap(appicon);
|
ui->label_appicon->setPixmap(appicon);
|
||||||
ui->pushButton_download->setEnabled(true);
|
ui->pushButton_download->setEnabled(true);
|
||||||
ui->pushButton->setEnabled(true);
|
ui->pushButton->setEnabled(true);
|
||||||
ui->pushButton_translate->setEnabled(true);
|
ui->pushButton_translate->setEnabled(true);
|
||||||
ui->pushButton_website->setEnabled(true);
|
ui->pushButton_website->setEnabled(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sendNotification(tr("Failed to load application icon."));
|
sendNotification(tr("Failed to load application icon."));
|
||||||
|
|
||||||
|
|
||||||
// 截图展示加载
|
// 截图展示加载
|
||||||
image_show *label_screen[5];
|
QList<image_show*> label_screen;
|
||||||
label_screen[0]=ui->screen_0;
|
label_screen << ui->screen_0 << ui->screen_1 << ui->screen_2 << ui->screen_3 << ui->screen_4;
|
||||||
label_screen[1]=ui->screen_1;
|
for (int i = 0; i < 5; i++) {
|
||||||
label_screen[2]=ui->screen_2;
|
|
||||||
label_screen[3]=ui->screen_3;
|
|
||||||
label_screen[4]=ui->screen_4;
|
|
||||||
for (int i=0;i<5;i++) {
|
|
||||||
QString cmd = "curl -o screen_"+QString::number(i+1)+".png "+urladdress+"screen_"+QString::number(i+1)+".png";
|
QString cmd = "curl -o screen_"+QString::number(i+1)+".png "+urladdress+"screen_"+QString::number(i+1)+".png";
|
||||||
get_json.terminate();
|
get_json.terminate();
|
||||||
get_json.start(cmd);
|
get_json.start(cmd);
|
||||||
@ -587,6 +593,7 @@ int Widget::loadappinfo(QUrl arg1)
|
|||||||
if(s){
|
if(s){
|
||||||
label_screen[i]->setImage(screen[i]);
|
label_screen[i]->setImage(screen[i]);
|
||||||
label_screen[i]->show();
|
label_screen[i]->show();
|
||||||
|
/*
|
||||||
switch(i){ // 故意为之,为了清除多余截图
|
switch(i){ // 故意为之,为了清除多余截图
|
||||||
case 0:
|
case 0:
|
||||||
label_screen[1]->hide();
|
label_screen[1]->hide();
|
||||||
@ -596,7 +603,8 @@ int Widget::loadappinfo(QUrl arg1)
|
|||||||
label_screen[3]->hide();
|
label_screen[3]->hide();
|
||||||
case 3:
|
case 3:
|
||||||
label_screen[4]->hide();
|
label_screen[4]->hide();
|
||||||
}
|
|
||||||
|
}*/
|
||||||
}else{
|
}else{
|
||||||
QFile::remove("screen_"+QString::number(i+1)+".png");
|
QFile::remove("screen_"+QString::number(i+1)+".png");
|
||||||
break;
|
break;
|
||||||
@ -691,6 +699,111 @@ void Widget::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::sltAppinfoResetUi()
|
||||||
|
{
|
||||||
|
// 先隐藏详情页负责显示截图的label
|
||||||
|
ui->screen_0->hide();
|
||||||
|
ui->screen_1->hide();
|
||||||
|
ui->screen_2->hide();
|
||||||
|
ui->screen_3->hide();
|
||||||
|
ui->screen_4->hide();
|
||||||
|
ui->label_appicon->clear();
|
||||||
|
ui->tag_community->hide();
|
||||||
|
ui->tag_ubuntu->hide();
|
||||||
|
ui->tag_deepin->hide();
|
||||||
|
ui->tag_uos->hide();
|
||||||
|
ui->tag_dtk5->hide();
|
||||||
|
ui->tag_dwine2->hide();
|
||||||
|
ui->tag_dwine5->hide();
|
||||||
|
ui->tag_a2d->hide();
|
||||||
|
|
||||||
|
// 重置UI状态
|
||||||
|
ui->pushButton_uninstall->hide();
|
||||||
|
ui->pushButton_website->setEnabled(false);
|
||||||
|
ui->pushButton->setEnabled(false);
|
||||||
|
ui->pushButton_translate->setEnabled(false);
|
||||||
|
ui->label_show->setText("Loading...");
|
||||||
|
ui->label_show->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sltAppinfoTags(QStringList *tagList)
|
||||||
|
{
|
||||||
|
foreach (const QString &tag, *tagList) {
|
||||||
|
if(tag=="community")
|
||||||
|
ui->tag_community->show();
|
||||||
|
else if(tag=="ubuntu")
|
||||||
|
ui->tag_ubuntu->show();
|
||||||
|
else if(tag=="deepin")
|
||||||
|
ui->tag_deepin->show();
|
||||||
|
else if(tag=="uos")
|
||||||
|
ui->tag_uos->show();
|
||||||
|
else if(tag=="dtk5")
|
||||||
|
ui->tag_dtk5->show();
|
||||||
|
else if(tag=="dwine2")
|
||||||
|
ui->tag_dwine2->show();
|
||||||
|
else if(tag=="dwine5")
|
||||||
|
ui->tag_dwine5->show();
|
||||||
|
else if(tag=="a2d")
|
||||||
|
ui->tag_a2d->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sltAppinfoDetails(QString *name, QString *details, QString *info,
|
||||||
|
QString *website, QString *packageName, QUrl *fileUrl,
|
||||||
|
bool isInstalled)
|
||||||
|
{
|
||||||
|
ui->label_appname->setText(appName = *name);
|
||||||
|
ui->label_appname->show();
|
||||||
|
ui->label_info->setText(*details);
|
||||||
|
ui->label_info->show();
|
||||||
|
ui->label_more->setText(*info);
|
||||||
|
ui->label_more->show();
|
||||||
|
pkgName = *packageName;
|
||||||
|
url = *fileUrl;
|
||||||
|
appweb = *website;
|
||||||
|
if(isInstalled){
|
||||||
|
ui->pushButton_download->setText(tr("Reinstall"));
|
||||||
|
ui->pushButton_uninstall->show();
|
||||||
|
}else {
|
||||||
|
ui->pushButton_download->setText(tr("Install"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sltAppinfoIcon(QPixmap *icon)
|
||||||
|
{
|
||||||
|
ui->label_appicon->setPixmap(*icon);
|
||||||
|
ui->label_appicon->show();
|
||||||
|
ui->pushButton_download->setEnabled(true);
|
||||||
|
ui->pushButton->setEnabled(true);
|
||||||
|
ui->pushButton_translate->setEnabled(true);
|
||||||
|
ui->pushButton_website->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sltAppinfoScreenshot(QPixmap *picture, int index)
|
||||||
|
{
|
||||||
|
if(picture != nullptr) {
|
||||||
|
screen[index] = *picture;
|
||||||
|
label_screen[index]->setImage(*picture);
|
||||||
|
label_screen[index]->show();
|
||||||
|
switch(index) { // 故意为之,为了清除多余截图
|
||||||
|
case 0:
|
||||||
|
label_screen[1]->hide();
|
||||||
|
case 1:
|
||||||
|
label_screen[2]->hide();
|
||||||
|
case 2:
|
||||||
|
label_screen[3]->hide();
|
||||||
|
case 3:
|
||||||
|
label_screen[4]->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sltAppinfoFinish()
|
||||||
|
{
|
||||||
|
ui->label_show->setText("");
|
||||||
|
ui->label_show->hide();
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::httpFinished() // 完成下载
|
void Widget::httpFinished() // 完成下载
|
||||||
{
|
{
|
||||||
file->flush();
|
file->flush();
|
||||||
@ -727,6 +840,7 @@ void Widget::on_pushButton_return_clicked()
|
|||||||
// chooseLeftMenu(13);
|
// chooseLeftMenu(13);
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
appinfoLoadThread.requestInterruption();
|
||||||
chooseLeftMenu(nowMenu);
|
chooseLeftMenu(nowMenu);
|
||||||
// if(themeIsDark){
|
// if(themeIsDark){
|
||||||
// QString darkurl=menuUrl[nowMenu].toString();
|
// QString darkurl=menuUrl[nowMenu].toString();
|
||||||
@ -746,13 +860,14 @@ void Widget::on_pushButton_return_clicked()
|
|||||||
void Widget::on_pushButton_refresh_clicked()
|
void Widget::on_pushButton_refresh_clicked()
|
||||||
{
|
{
|
||||||
if(ui->stackedWidget->currentIndex() == 2) //如果在详情页面要重新触发UrlChanged
|
if(ui->stackedWidget->currentIndex() == 2) //如果在详情页面要重新触发UrlChanged
|
||||||
emit ui->webEngineView->urlChanged(ui->webEngineView->url());
|
emit ui->webEngineView->urlChanged(ui->webEngineView->url());
|
||||||
else
|
else
|
||||||
ui->webEngineView->reload();
|
ui->webEngineView->reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::on_comboBox_server_currentIndexChanged(const QString &arg1)
|
void Widget::on_comboBox_server_currentIndexChanged(const QString &arg1)
|
||||||
{
|
{
|
||||||
|
appinfoLoadThread.setServer(arg1); // 服务器信息更新
|
||||||
if(configCanSave){
|
if(configCanSave){
|
||||||
ui->label_setting1->show();
|
ui->label_setting1->show();
|
||||||
QSettings *setConfig=new QSettings(QDir::homePath()+"/.config/spark-store/config.ini",QSettings::IniFormat);
|
QSettings *setConfig=new QSettings(QDir::homePath()+"/.config/spark-store/config.ini",QSettings::IniFormat);
|
||||||
@ -785,70 +900,70 @@ void Widget::on_pushButton_updateServer_clicked()
|
|||||||
void Widget::on_pushButton_updateApt_clicked()
|
void Widget::on_pushButton_updateApt_clicked()
|
||||||
{
|
{
|
||||||
QtConcurrent::run([=](){
|
QtConcurrent::run([=](){
|
||||||
ui->pushButton_updateApt->setEnabled(false);
|
ui->pushButton_updateApt->setEnabled(false);
|
||||||
ui->label_aptserver->setText(tr("Updating, please wait..."));
|
ui->label_aptserver->setText(tr("Updating, please wait..."));
|
||||||
|
|
||||||
std::fstream sourcesList, policy, update;
|
std::fstream sourcesList, policy, update;
|
||||||
QDir tmpdir("/tmp");
|
QDir tmpdir("/tmp");
|
||||||
auto tmpPath = QString::fromUtf8(TMP_PATH).toStdString();
|
auto tmpPath = QString::fromUtf8(TMP_PATH).toStdString();
|
||||||
bool unknownError = true;
|
bool unknownError = true;
|
||||||
|
|
||||||
tmpdir.mkpath("spark-store");
|
tmpdir.mkpath("spark-store");
|
||||||
sourcesList.open(tmpPath + "/sparkstore.list", std::ios::out);
|
sourcesList.open(tmpPath + "/sparkstore.list", std::ios::out);
|
||||||
//policy.open(tmpPath + "/sparkstore", std::ios::out);
|
//policy.open(tmpPath + "/sparkstore", std::ios::out);
|
||||||
// 商店已经下架会替换系统库的包,优先级policy弃用
|
// 商店已经下架会替换系统库的包,优先级policy弃用
|
||||||
|
|
||||||
if(sourcesList /*&& policy*/) {
|
if(sourcesList /*&& policy*/) {
|
||||||
auto serverAddr = ui->comboBox_server->currentText();
|
auto serverAddr = ui->comboBox_server->currentText();
|
||||||
|
|
||||||
sourcesList << "deb [by-hash=force] ";
|
sourcesList << "deb [by-hash=force] ";
|
||||||
sourcesList << serverAddr.toUtf8().toStdString();
|
sourcesList << serverAddr.toUtf8().toStdString();
|
||||||
sourcesList << " /";
|
sourcesList << " /";
|
||||||
sourcesList.close();
|
sourcesList.close();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
policy << "Package: *\n"
|
policy << "Package: *\n"
|
||||||
"Pin: origin *" << serverAddr.mid(serverAddr.indexOf('.')).toUtf8().toStdString() << "\n"
|
"Pin: origin *" << serverAddr.mid(serverAddr.indexOf('.')).toUtf8().toStdString() << "\n"
|
||||||
"Pin-Priority: 90"; // 降低星火源的优先级,防止从星火安装已存在的系统包,破坏依赖
|
"Pin-Priority: 90"; // 降低星火源的优先级,防止从星火安装已存在的系统包,破坏依赖
|
||||||
policy.close();
|
policy.close();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
update.open(tmpPath + "/update.sh",std::ios::out);
|
update.open(tmpPath + "/update.sh",std::ios::out);
|
||||||
if(update) {
|
if(update) {
|
||||||
unknownError = false;
|
unknownError = false;
|
||||||
update << "#!/bin/sh\n"
|
update << "#!/bin/sh\n"
|
||||||
"mv " + tmpPath + "/sparkstore.list /etc/apt/sources.list.d/sparkstore.list && "
|
"mv " + tmpPath + "/sparkstore.list /etc/apt/sources.list.d/sparkstore.list && "
|
||||||
// "mv " + tmpPath + "/sparkstore /etc/apt/preferences.d/sparkstore && "
|
// "mv " + tmpPath + "/sparkstore /etc/apt/preferences.d/sparkstore && "
|
||||||
"apt update";
|
"apt update";
|
||||||
update.close();
|
update.close();
|
||||||
|
|
||||||
system(("chmod +x " + tmpPath + "/update.sh").c_str());
|
system(("chmod +x " + tmpPath + "/update.sh").c_str());
|
||||||
QProcess runupdate;
|
QProcess runupdate;
|
||||||
runupdate.start(QString::fromStdString("pkexec " + tmpPath + "/update.sh"));
|
runupdate.start(QString::fromStdString("pkexec " + tmpPath + "/update.sh"));
|
||||||
runupdate.waitForFinished();
|
runupdate.waitForFinished();
|
||||||
QString error = runupdate.readAllStandardError();
|
QString error = runupdate.readAllStandardError();
|
||||||
|
|
||||||
QStringList everyError = error.split("\n");
|
QStringList everyError = error.split("\n");
|
||||||
bool haveError = false;
|
bool haveError = false;
|
||||||
for (int i=0; i < everyError.size(); i++) {
|
for (int i=0; i < everyError.size(); i++) {
|
||||||
if(everyError[i].left(2) == "E:") {
|
if(everyError[i].left(2) == "E:") {
|
||||||
haveError = true;
|
haveError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!haveError) {
|
if(!haveError) {
|
||||||
ui->label_aptserver->setText("deb [by-hash=force] " + ui->comboBox_server->currentText().toUtf8() + " /");
|
ui->label_aptserver->setText("deb [by-hash=force] " + ui->comboBox_server->currentText().toUtf8() + " /");
|
||||||
} else {
|
} else {
|
||||||
ui->label_aptserver->setText(tr("Apt has reported an error. Please use apt update in terminal to locate the problem."));
|
ui->label_aptserver->setText(tr("Apt has reported an error. Please use apt update in terminal to locate the problem."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unknownError) {
|
if(unknownError) {
|
||||||
ui->label_aptserver->setText(tr("Unknown error!"));
|
ui->label_aptserver->setText(tr("Unknown error!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pushButton_updateApt->setEnabled(true);
|
ui->pushButton_updateApt->setEnabled(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -983,10 +1098,16 @@ void Widget::on_webEngineView_urlChanged(const QUrl &arg1)
|
|||||||
ui->pushButton_download->setEnabled(false);
|
ui->pushButton_download->setEnabled(false);
|
||||||
ui->stackedWidget->setCurrentIndex(2);
|
ui->stackedWidget->setCurrentIndex(2);
|
||||||
qDebug()<<"https://demo-one-vert.vercel.app/"+type_name+"/"+pname;
|
qDebug()<<"https://demo-one-vert.vercel.app/"+type_name+"/"+pname;
|
||||||
|
/*
|
||||||
load.cancel();//打开并发加载线程前关闭正在执行的线程
|
load.cancel();//打开并发加载线程前关闭正在执行的线程
|
||||||
load = QtConcurrent::run([=](){
|
load = QtConcurrent::run([=](){
|
||||||
int loadresult = loadappinfo(arg1);
|
int loadresult = loadappinfo(arg1);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
appinfoLoadThread.requestInterruption();
|
||||||
|
appinfoLoadThread.wait(100);
|
||||||
|
appinfoLoadThread.setUrl(arg1);
|
||||||
|
appinfoLoadThread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,7 +1130,7 @@ void Widget::on_webEngineView_loadProgress(int progress)
|
|||||||
void Widget::on_webEngineView_loadFinished(bool arg1)
|
void Widget::on_webEngineView_loadFinished(bool arg1)
|
||||||
{
|
{
|
||||||
if(arg1){
|
if(arg1){
|
||||||
m_loadweb->setValue(0);
|
m_loadweb->setValue(0);
|
||||||
}else {
|
}else {
|
||||||
m_loadweb->setValue(0);
|
m_loadweb->setValue(0);
|
||||||
m_loaderror->show();
|
m_loaderror->show();
|
||||||
|
17
widget.h
17
widget.h
@ -21,6 +21,9 @@
|
|||||||
#include <DTitlebar>
|
#include <DTitlebar>
|
||||||
#include <DSearchEdit>
|
#include <DSearchEdit>
|
||||||
#include <progressload.h>
|
#include <progressload.h>
|
||||||
|
#include "workerthreads.h"
|
||||||
|
#include "image_show.h"
|
||||||
|
|
||||||
#define LIST_MAX 99 //一次最多下载数量
|
#define LIST_MAX 99 //一次最多下载数量
|
||||||
#define TMP_PATH "/tmp/spark-store"
|
#define TMP_PATH "/tmp/spark-store"
|
||||||
|
|
||||||
@ -56,6 +59,17 @@ private slots:
|
|||||||
void httpFinished();
|
void httpFinished();
|
||||||
void httpReadyRead();
|
void httpReadyRead();
|
||||||
void updateDataReadProgress(qint64,qint64);
|
void updateDataReadProgress(qint64,qint64);
|
||||||
|
|
||||||
|
// SpkAppInfoLoaderThread的槽函数
|
||||||
|
void sltAppinfoResetUi();
|
||||||
|
void sltAppinfoTags(QStringList *tagList);
|
||||||
|
void sltAppinfoDetails(QString *name, QString *details, QString *info,
|
||||||
|
QString *website, QString *packageName,
|
||||||
|
QUrl *fileUrl, bool isInstalled);
|
||||||
|
void sltAppinfoIcon(QPixmap *icon);
|
||||||
|
void sltAppinfoScreenshot(QPixmap *picture, int index);
|
||||||
|
void sltAppinfoFinish();
|
||||||
|
|
||||||
void on_pushButton_download_clicked();
|
void on_pushButton_download_clicked();
|
||||||
void on_pushButton_return_clicked();
|
void on_pushButton_return_clicked();
|
||||||
void on_comboBox_server_currentIndexChanged(const QString &arg1);
|
void on_comboBox_server_currentIndexChanged(const QString &arg1);
|
||||||
@ -125,6 +139,9 @@ private:
|
|||||||
DSearchEdit *searchEdit=new DSearchEdit;
|
DSearchEdit *searchEdit=new DSearchEdit;
|
||||||
DTitlebar *titlebar;
|
DTitlebar *titlebar;
|
||||||
|
|
||||||
|
QList<image_show*> label_screen;
|
||||||
|
SpkAppInfoLoaderThread appinfoLoadThread;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WIDGET_H
|
#endif // WIDGET_H
|
||||||
|
152
workerthreads.cpp
Normal file
152
workerthreads.cpp
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include "workerthreads.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
void SpkAppInfoLoaderThread::run()
|
||||||
|
{
|
||||||
|
emit requestResetUi();
|
||||||
|
|
||||||
|
QProcess get_json;
|
||||||
|
QString urladdress, deatils, more, packagename, appweb;
|
||||||
|
QDir dir("/tmp");
|
||||||
|
bool isInstalled;
|
||||||
|
dir.mkdir("spark-store");
|
||||||
|
QDir::setCurrent("/tmp/spark-store");
|
||||||
|
|
||||||
|
get_json.start("curl -o app.json " + targetUrl.toString());
|
||||||
|
if(waitDownload(get_json) == -1)
|
||||||
|
return;
|
||||||
|
if(get_json.exitCode())
|
||||||
|
{
|
||||||
|
Widget::sendNotification(tr("Failed to download app info. Please check internet connection."));
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile app_json("app.json");
|
||||||
|
if(app_json.open(QIODevice::ReadOnly)){
|
||||||
|
// 成功得到json文件
|
||||||
|
QByteArray json_array = app_json.readAll();
|
||||||
|
// 将路径转化为相应源的下载路径
|
||||||
|
urladdress = targetUrl.toString().left(targetUrl.toString().length()-8);
|
||||||
|
QStringList downloadurl=urladdress.split("/");
|
||||||
|
|
||||||
|
QString deburl = serverUrl;
|
||||||
|
deburl = deburl.left(urladdress.length()-1);
|
||||||
|
urladdress = "https://cdn.jsdelivr.net/gh/Jerrywang959/jsonpng@master/"; // 使用图片专用服务器请保留这行,删除后将使用源服务器
|
||||||
|
urladdress = urladdress.left(urladdress.length()-1);
|
||||||
|
|
||||||
|
for (int i=3;i<downloadurl.size();i++) {
|
||||||
|
urladdress+="/"+downloadurl[i];
|
||||||
|
deburl+="/"+downloadurl[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路径转化完成
|
||||||
|
QJsonObject json= QJsonDocument::fromJson(json_array).object();
|
||||||
|
QString appName = json["Name"].toString();
|
||||||
|
QUrl fileUrl = deburl + json["Filename"].toString();
|
||||||
|
|
||||||
|
// 软件信息加载
|
||||||
|
QString details;
|
||||||
|
details = tr("PkgName: ") + json["Pkgname"].toString()+"\n";
|
||||||
|
details += tr("Version: ") + json["Version"].toString()+"\n";
|
||||||
|
if(json["Author"].toString() != "" && json["Author"].toString() != " "){
|
||||||
|
details += tr("Author: ") + json["Author"].toString() + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["Website"].toString() != "" && json["Website"].toString() != " "){
|
||||||
|
details += tr("Official Site: ") + json["Website"].toString() + "\n";
|
||||||
|
//ui->pushButton_website->show(); move to setinfo slot
|
||||||
|
appweb=json["Website"].toString();
|
||||||
|
}
|
||||||
|
details+=tr("Contributor: ")+json["Contributor"].toString()+"\n";
|
||||||
|
details+=tr("Update Time: ")+json["Update"].toString()+"\n";
|
||||||
|
details+=tr("Installed Size: ")+json["Size"].toString()+"\n";
|
||||||
|
more = json["More"].toString();
|
||||||
|
|
||||||
|
QProcess isInstall;
|
||||||
|
packagename = json["Pkgname"].toString();
|
||||||
|
isInstall.start("dpkg -s "+json["Pkgname"].toString());
|
||||||
|
isInstall.waitForFinished();
|
||||||
|
int error=QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||||
|
if(error==0)
|
||||||
|
isInstalled = true;
|
||||||
|
else
|
||||||
|
isInstalled = false;
|
||||||
|
|
||||||
|
emit requestSetAppInformation(&appName, &details, &more, &appweb, &packagename, &fileUrl, isInstalled);
|
||||||
|
|
||||||
|
//tag加载
|
||||||
|
QString tags=json["Tags"].toString();
|
||||||
|
QStringList tagList=tags.split(";");
|
||||||
|
emit requestSetTags(&tagList);
|
||||||
|
|
||||||
|
// 图标加载
|
||||||
|
get_json.start("curl -o icon.png "+urladdress+"icon.png");
|
||||||
|
if(waitDownload(get_json) == -1)
|
||||||
|
return;
|
||||||
|
if(!get_json.exitCode()) {
|
||||||
|
QPixmap appicon("icon.png");
|
||||||
|
emit finishedIconLoad(&appicon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Widget::sendNotification(tr("Failed to load application icon."));
|
||||||
|
|
||||||
|
|
||||||
|
// 截图展示加载
|
||||||
|
QPixmap screenshotCache[5];
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
QString cmd = "curl -o screen_"+QString::number(i+1)+".png "+urladdress+"screen_"+QString::number(i+1)+".png";
|
||||||
|
get_json.start(cmd);
|
||||||
|
if(waitDownload(get_json) == -1)
|
||||||
|
return;
|
||||||
|
bool s = screenshotCache[i].load(QString(TMP_PATH) + "/screen_"+QString::number(i+1)+".png");
|
||||||
|
if(s){
|
||||||
|
emit finishedScreenshotLoad(&screenshotCache[i], i);
|
||||||
|
}else{
|
||||||
|
emit finishedScreenshotLoad(nullptr, i);
|
||||||
|
QFile::remove("screen_"+QString::number(i+1)+".png");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit finishAllLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkAppInfoLoaderThread::setUrl(const QUrl &url)
|
||||||
|
{
|
||||||
|
targetUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkAppInfoLoaderThread::setServer(const QString &server)
|
||||||
|
{
|
||||||
|
serverUrl = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkAppInfoLoaderThread::downloadFinished(int exitcode, QProcess::ExitStatus status)
|
||||||
|
{
|
||||||
|
Q_UNUSED(exitcode);
|
||||||
|
Q_UNUSED(status);
|
||||||
|
qDebug() << "Finish one download";
|
||||||
|
finishedDownload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SpkAppInfoLoaderThread::waitDownload(QProcess& downloader)
|
||||||
|
{
|
||||||
|
while(!downloader.waitForFinished(100))
|
||||||
|
{
|
||||||
|
if(downloader.state() == QProcess::NotRunning)
|
||||||
|
return -1;
|
||||||
|
if(this->isInterruptionRequested())
|
||||||
|
{
|
||||||
|
downloader.terminate();
|
||||||
|
downloader.waitForFinished(-1);
|
||||||
|
qDebug() << "Appinfo loader thread was forcefully terminated";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
36
workerthreads.h
Normal file
36
workerthreads.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef WORKERTHREADS_H
|
||||||
|
#define WORKERTHREADS_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
class SpkAppInfoLoaderThread Q_DECL_FINAL : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
//explicit SpkAppInfoLoaderThread() = default;
|
||||||
|
void run() Q_DECL_OVERRIDE;
|
||||||
|
public slots:
|
||||||
|
void setUrl(const QUrl &url);
|
||||||
|
void setServer(const QString &server);
|
||||||
|
void downloadFinished(int exitcode, QProcess::ExitStatus status);
|
||||||
|
signals:
|
||||||
|
void requestResetUi();
|
||||||
|
void requestSetTags(QStringList *tagList);
|
||||||
|
void requestSetAppInformation(QString *name, QString *details, QString *info,
|
||||||
|
QString *website, QString *packageName,
|
||||||
|
QUrl *fileUrl, bool isInstalled);
|
||||||
|
void finishedIconLoad(QPixmap *icon);
|
||||||
|
void finishedScreenshotLoad(QPixmap *icon, int index); // 该信号必须以BlockingQueued方式连接
|
||||||
|
void finishAllLoading(); // 该信号必须以BlockingQueued方式连接
|
||||||
|
private:
|
||||||
|
int waitDownload(QProcess& downloader);
|
||||||
|
QUrl targetUrl;
|
||||||
|
QString serverUrl;
|
||||||
|
bool finishedDownload = false;
|
||||||
|
int downloaderRetval = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WORKERTHREADS_H
|
Loading…
x
Reference in New Issue
Block a user