分支后首次推送;更新所有代码至内部最新测试版
48
README.md
@@ -1,29 +1,23 @@
|
||||
# 🍓FRAISEMOE Addons Installer🍓
|
||||
# 🍓FRAISEMOE2-Installer🍓
|
||||
|
||||
```
|
||||
|
||||
🔊 通知:“FraiseMoe Addons Installer”完成了其作为测试版本的用途,感谢广大用户的支持与陪伴。
|
||||
将于2025年7月14日00时00分起,“FraiseMoe Addons Installer”GitHub仓库将进行归档,下载服务将永久停止使用。
|
||||
本应用程式的完全重构版本将于2025年7月14日23时59分,将在“https://github.com/Yanam1Anna/FRAISEMOE-Addons-Manager”发布。
|
||||
因原 CDN 服务成本高且服务器长期高负载,我们无力继续提供免费服务。且此版本开源效果不佳,故全新版本采用闭源方式发布。
|
||||
自新版本发布,此版本归档之日起,为维持服务器收支平衡,可能引入收费机制以保障持续运营,或项目将进入生命周期管理阶段。
|
||||
|
||||
🔊 注意:本库仍然努力更新中,大部分文档不可用,敬请谅解。
|
||||
```
|
||||
|
||||
<!-- PROJECT SHIELDS -->
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/stargazers" class="shield">
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/stargazers" class="shield">
|
||||
<img src="https://img.shields.io/github/stars/Yanam1Anna/FRAISEMOE-Addons-Installer?style=flat-square&label=%E2%AD%90%20Stars&color=blue" alt="Stars">
|
||||
</a>
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/issues" class="shield">
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/issues" class="shield">
|
||||
<img src="https://img.shields.io/github/issues/Yanam1Anna/FRAISEMOE-Addons-Installer?style=flat-square&label=%F0%9F%92%AC%20%E6%8A%A5%E5%91%8A%E9%97%AE%E9%A2%98%2F%E6%8B%89%E5%8F%96%E8%AF%B7%E6%B1%82&color=blue" alt="Issues/Pull Requests">
|
||||
</a>
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/releases/latest" class="shield">
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/releases/latest" class="shield">
|
||||
<img src="https://img.shields.io/github/v/release/Yanam1Anna/FRAISEMOE-Addons-Installer?style=flat-square&label=%F0%9F%92%AF%20%E6%9C%80%E6%96%B0%E7%89%88%E6%9C%AC&color=blue" alt="Latest Release">
|
||||
</a>
|
||||
<img src="https://img.shields.io/github/downloads/Yanam1Anna/FRAISEMOE-Addons-Installer/total?style=flat-square&label=%F0%9F%93%A5%20%E4%B8%8B%E8%BD%BD%E6%AC%A1%E6%95%B0&color=blue" alt="Download Count" class="shield">
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/LICENSE" class="shield">
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/blob/master/LICENSE" class="shield">
|
||||
<img src="https://img.shields.io/github/license/Yanam1Anna/FRAISEMOE-Addons-Installer?style=flat-square&label=%F0%9F%93%96%20%E5%BC%80%E6%BA%90%E5%8D%8F%E8%AE%AE&color=blue" alt="License">
|
||||
</a>
|
||||
<img src="https://img.shields.io/badge/Python-3.12.10-blue?style=flat-square&logo=python" alt="Python" class="shield">
|
||||
@@ -43,21 +37,21 @@
|
||||
⚠️ 本工具为非官方工具,不代表官方立场 ⚠️
|
||||
<br />
|
||||
<br />
|
||||
<strong><a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer">探索本项目的文档 »</a></strong>
|
||||
⚠️ 本NEXT版本目前处于持续开发阶段,不保证任何稳定性 ⚠️
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/issues">报告Bug</a>
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/issues">报告Bug</a>
|
||||
·
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/issues">提出新特性</a>
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/issues">提出新特性</a>
|
||||
·
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/FAQ.md">【用前必看】使用须知</a>
|
||||
<a href="https://github.com/hyb-oyqq/FRAISEMOE2-Installer/blob/master/FAQ.md">【用前必看】使用须知</a>
|
||||
<br />
|
||||
</p>
|
||||
|
||||
<!-- LANGUAGE -->
|
||||
<p align="center">
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer">中文</a> |
|
||||
<a href="https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/README-en.md">English</a>
|
||||
<a href="#">English</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
@@ -79,42 +73,34 @@
|
||||
|
||||
### 📥 安装
|
||||
|
||||
请从 [应用发布页面](https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/releases) 下载最新版本的应用程序。
|
||||
请从 [应用发布页面](https://github.com/hyb-oyqq/FRAISEMOE2-Installer/releases) 下载最新版本的应用程序。
|
||||
|
||||

|
||||
|
||||
### ❗ 使用步骤
|
||||
|
||||
1. **重要提示**:使用前请务必阅读 [使用须知文档](https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/FAQ.md)。
|
||||
1. **重要提示**:使用前请务必阅读 [使用须知文档](https://github.com/hyb-oyqq/FRAISEMOE2-Installer/blob/master/FAQ.md)。
|
||||
2. **详细教程**:参考 [视频教学](https://www.bilibili.com/video/BV1hn9UYwE6p/)。
|
||||
|
||||
### ⭕ 版本控制
|
||||
|
||||
该项目使用 Git 进行版本管理,您可以在 [应用发布页面](https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/releases) 查看当前可用版本。
|
||||
该项目使用 Git 进行版本管理,您可以在 [应用发布页面](https://github.com/hyb-oyqq/FRAISEMOE2-Installer/releases) 查看当前可用版本。
|
||||
|
||||
---
|
||||
|
||||
## 💡 注意事项
|
||||
|
||||
1. 请勿使用经过二次修改的应用:若使用未知来源或修改后的应用导致个人利益受损,作者和开发人员不承担任何责任。
|
||||
2. 请遵循所有规则:请严格遵守 [使用须知文档](https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/FAQ.md) 和本文档中的规则,如有违反,作者和开发人员不承担责任。
|
||||
2. 请遵循所有规则:请严格遵守 [使用须知文档](https://github.com/hyb-oyqq/FRAISEMOE2-Installer/blob/master/FAQ.md) 和本文档中的规则,如有违反,作者和开发人员不承担责任。
|
||||
3. 免费开源:本应用免费、开源,如有通过非免费途径获取,请立即向来源申请退款并积极维权。
|
||||
|
||||
---
|
||||
|
||||
## 📝 作者
|
||||
|
||||
- [Yanam1Anna](https://github.com/Yanam1Anna)   Email: [icon.hirasawayui@gmail.com](mailto:icon.hirasawayui@gmail.com)
|
||||
|
||||
## 🧧 捐助(遵循自愿原则,非强制,一经赞赏无法退还)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/Yanam1Anna/FRAISEMOE-Addons-Installer/refs/heads/master/introduction_imgs/donations.png" alt="Donations" width="500">
|
||||
|
||||
## 🎉 特别鸣谢
|
||||
|
||||
- [Yanam1Anna](https://github.com/Yanam1Anna): 本项目的原作者,提供了大量代码和资源。
|
||||
- [HTony03](https://github.com/HTony03):对于本项目部分源码的重构、逻辑优化和功能实现提供了大力支持。
|
||||
- [Akatsuki Misaki](https://github.com/Akatsuki-Misaki):对于本项目云端资源存储提供了大力支持。
|
||||
|
||||
## 📖 协议
|
||||
|
||||
此应用根据 [GPL-3.0](https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/LICENSE) 许可证授权。请参阅 [LICENSE](https://github.com/Yanam1Anna/FRAISEMOE-Addons-Installer/blob/master/LICENSE) 文件了解更多信息。
|
||||
此应用根据 [GPL-3.0](https://github.com/hyb-oyqq/FRAISEMOE2-Installer/blob/master/LICENSE) 许可证授权。请参阅 [LICENSE](https://github.com/hyb-oyqq/FRAISEMOE2-Installer/blob/master/LICENSE) 文件了解更多信息。
|
||||
|
||||
|
Before Width: | Height: | Size: 350 KiB |
236
source/GUI.py
@@ -1,236 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'Main.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.7.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (
|
||||
QCoreApplication,
|
||||
QDate,
|
||||
QDateTime,
|
||||
QLocale,
|
||||
QMetaObject,
|
||||
QObject,
|
||||
QPoint,
|
||||
QRect,
|
||||
QSize,
|
||||
QTime,
|
||||
QUrl,
|
||||
Qt,
|
||||
)
|
||||
from PySide6.QtGui import (
|
||||
QBrush,
|
||||
QColor,
|
||||
QConicalGradient,
|
||||
QCursor,
|
||||
QFont,
|
||||
QFontDatabase,
|
||||
QGradient,
|
||||
QIcon,
|
||||
QImage,
|
||||
QKeySequence,
|
||||
QLinearGradient,
|
||||
QPainter,
|
||||
QPalette,
|
||||
QPixmap,
|
||||
QRadialGradient,
|
||||
QTransform,
|
||||
)
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QLabel,
|
||||
QPushButton,
|
||||
QSizePolicy,
|
||||
QSplitter,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
from pic_data import img_data
|
||||
from PySide6.QtCore import QByteArray
|
||||
import base64
|
||||
|
||||
|
||||
class Ui_mainwin(object):
|
||||
|
||||
def setupUi(self, mainwin):
|
||||
if not mainwin.objectName():
|
||||
mainwin.setObjectName("mainwin")
|
||||
mainwin.setWindowModality(Qt.WindowModality.NonModal)
|
||||
mainwin.resize(1280, 720)
|
||||
mainwin.setMinimumSize(QSize(1280, 720))
|
||||
mainwin.setMaximumSize(QSize(1280, 720))
|
||||
|
||||
pixmap = QPixmap()
|
||||
|
||||
icon = QIcon()
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["icon"])))
|
||||
icon.addPixmap(pixmap)
|
||||
|
||||
mainwin.setWindowIcon(icon)
|
||||
|
||||
self.mainbg = QLabel(mainwin)
|
||||
self.mainbg.setObjectName("mainbg")
|
||||
self.mainbg.setEnabled(True)
|
||||
self.mainbg.setGeometry(QRect(0, 0, 1280, 720))
|
||||
self.mainbg.setMinimumSize(QSize(1280, 720))
|
||||
self.mainbg.setMaximumSize(QSize(1280, 720))
|
||||
self.mainbg.setTextFormat(Qt.TextFormat.AutoText)
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["bg"])))
|
||||
|
||||
self.mainbg.setPixmap(pixmap)
|
||||
self.mainbg.setScaledContents(False)
|
||||
self.mainbg.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.cover = QSplitter(mainwin)
|
||||
self.cover.setObjectName("cover")
|
||||
self.cover.setGeometry(QRect(0, 320, 213, 400))
|
||||
self.cover.setOrientation(Qt.Orientation.Vertical)
|
||||
self.Cover_1 = QLabel(self.cover)
|
||||
self.Cover_1.setObjectName("Cover_1")
|
||||
self.Cover_1.setMinimumSize(QSize(213, 100))
|
||||
self.Cover_1.setMaximumSize(QSize(213, 100))
|
||||
self.Cover_1.setTextFormat(Qt.TextFormat.AutoText)
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["vol_1_cover"])))
|
||||
self.Cover_1.setPixmap(pixmap)
|
||||
|
||||
self.Cover_1.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.cover.addWidget(self.Cover_1)
|
||||
self.Cover_2 = QLabel(self.cover)
|
||||
self.Cover_2.setObjectName("Cover_2")
|
||||
self.Cover_2.setMinimumSize(QSize(213, 100))
|
||||
self.Cover_2.setMaximumSize(QSize(213, 100))
|
||||
self.Cover_2.setTextFormat(Qt.TextFormat.AutoText)
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["vol_2_cover"])))
|
||||
self.Cover_2.setPixmap(pixmap)
|
||||
|
||||
self.Cover_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.cover.addWidget(self.Cover_2)
|
||||
self.Cover_3 = QLabel(self.cover)
|
||||
self.Cover_3.setObjectName("Cover_3")
|
||||
self.Cover_3.setMinimumSize(QSize(213, 100))
|
||||
self.Cover_3.setMaximumSize(QSize(213, 100))
|
||||
self.Cover_3.setTextFormat(Qt.TextFormat.AutoText)
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["vol_3_cover"])))
|
||||
self.Cover_3.setPixmap(pixmap)
|
||||
|
||||
self.Cover_3.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.cover.addWidget(self.Cover_3)
|
||||
self.Cover_4 = QLabel(self.cover)
|
||||
self.Cover_4.setObjectName("Cover_4")
|
||||
self.Cover_4.setMinimumSize(QSize(213, 100))
|
||||
self.Cover_4.setMaximumSize(QSize(213, 100))
|
||||
self.Cover_4.setTextFormat(Qt.TextFormat.AutoText)
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["vol_4_cover"])))
|
||||
self.Cover_4.setPixmap(pixmap)
|
||||
|
||||
self.Cover_4.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.cover.addWidget(self.Cover_4)
|
||||
self.menubg = QLabel(mainwin)
|
||||
self.menubg.setObjectName("menubg")
|
||||
self.menubg.setGeometry(QRect(800, 0, 480, 720))
|
||||
self.menubg.setMinimumSize(QSize(480, 720))
|
||||
self.menubg.setMaximumSize(QSize(480, 720))
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["menubg"])))
|
||||
self.menubg.setPixmap(pixmap)
|
||||
|
||||
self.menubg.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.layoutWidget = QWidget(mainwin)
|
||||
self.layoutWidget.setObjectName("layoutWidget")
|
||||
self.layoutWidget.setGeometry(QRect(940, 340, 212, 204))
|
||||
self.button = QVBoxLayout(self.layoutWidget)
|
||||
self.button.setObjectName("button")
|
||||
self.button.setContentsMargins(0, 0, 0, 0)
|
||||
self.startbtn = QPushButton(self.layoutWidget)
|
||||
self.startbtn.setObjectName("startbtn")
|
||||
self.startbtn.setMinimumSize(QSize(210, 98))
|
||||
self.startbtn.setMaximumSize(QSize(210, 98))
|
||||
|
||||
icon1 = QIcon()
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["btn01bg"])))
|
||||
icon1.addPixmap(pixmap)
|
||||
|
||||
self.startbtn.setIcon(icon1)
|
||||
self.startbtn.setIconSize(QSize(210, 98))
|
||||
self.startbtn.setFlat(True)
|
||||
|
||||
self.button.addWidget(self.startbtn)
|
||||
|
||||
self.exitbtn = QPushButton(self.layoutWidget)
|
||||
self.exitbtn.setObjectName("exitbtn")
|
||||
self.exitbtn.setMinimumSize(QSize(210, 98))
|
||||
self.exitbtn.setMaximumSize(QSize(210, 98))
|
||||
|
||||
icon2 = QIcon()
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["btn02bg"])))
|
||||
icon2.addPixmap(pixmap)
|
||||
|
||||
self.exitbtn.setIcon(icon2)
|
||||
self.exitbtn.setIconSize(QSize(210, 98))
|
||||
self.exitbtn.setFlat(True)
|
||||
|
||||
self.button.addWidget(self.exitbtn)
|
||||
|
||||
self.sup_info = QLabel(mainwin)
|
||||
self.sup_info.setObjectName("sup_info")
|
||||
self.sup_info.setGeometry(QRect(0, 230, 213, 100))
|
||||
self.sup_info.setMinimumSize(QSize(213, 100))
|
||||
self.sup_info.setMaximumSize(QSize(213, 100))
|
||||
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["support_info"])))
|
||||
self.sup_info.setPixmap(pixmap)
|
||||
|
||||
self.future_info = QLabel(mainwin)
|
||||
self.future_info.setObjectName("future_info")
|
||||
self.future_info.setGeometry(QRect(860, 700, 370, 16))
|
||||
self.future_info.setMinimumSize(QSize(370, 16))
|
||||
self.future_info.setMaximumSize(QSize(370, 16))
|
||||
font = QFont()
|
||||
font.setFamilies(["Consolas"])
|
||||
font.setBold(True)
|
||||
font.setItalic(True)
|
||||
self.future_info.setFont(font)
|
||||
self.future_info.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.mainbg.raise_()
|
||||
self.cover.raise_()
|
||||
self.menubg.raise_()
|
||||
self.layoutWidget.raise_()
|
||||
self.future_info.raise_()
|
||||
self.sup_info.raise_()
|
||||
|
||||
self.retranslateUi(mainwin)
|
||||
|
||||
QMetaObject.connectSlotsByName(mainwin)
|
||||
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, mainwin):
|
||||
mainwin.setWindowTitle(
|
||||
QCoreApplication.translate(
|
||||
"mainwin", "FRAISEMOE Addons Installer V4.10.0.17496", None
|
||||
)
|
||||
)
|
||||
self.mainbg.setText("")
|
||||
self.Cover_1.setText("")
|
||||
self.Cover_2.setText("")
|
||||
self.Cover_3.setText("")
|
||||
self.Cover_4.setText("")
|
||||
self.menubg.setText("")
|
||||
self.startbtn.setText("")
|
||||
self.exitbtn.setText("")
|
||||
self.sup_info.setText("")
|
||||
self.future_info.setText(
|
||||
QCoreApplication.translate(
|
||||
"mainwin", "Nekopara After La Vraie Famille COMMING SOON IN 2025", None
|
||||
)
|
||||
)
|
||||
|
||||
# retranslateUi
|
||||
BIN
source/IMG/After/voaf_ga01.jpg
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
source/IMG/After/voaf_ga02.jpg
Normal file
|
After Width: | Height: | Size: 179 KiB |
BIN
source/IMG/BG/bg1.jpg
Normal file
|
After Width: | Height: | Size: 571 KiB |
BIN
source/IMG/BG/bg2.jpg
Normal file
|
After Width: | Height: | Size: 250 KiB |
BIN
source/IMG/BG/bg3.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
source/IMG/BG/bg4.jpg
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
source/IMG/BG/menubg.jpg
Normal file
|
After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
BIN
source/IMG/LOGO/gl_head_logo_jp.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
source/IMG/LOGO/vo01_logo.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
source/IMG/LOGO/vo02_logo.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
source/IMG/LOGO/vo03_logo.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
source/IMG/LOGO/vo04_logo.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
source/IMG/LOGO/voaf_logo.png
Normal file
|
After Width: | Height: | Size: 327 KiB |
BIN
source/IMG/vol4/vo04_ga01.jpg
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
source/IMG/vol4/vo04_ga05.jpg
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
source/IMG/vol4/vo04_ga06.jpg
Normal file
|
After Width: | Height: | Size: 197 KiB |
BIN
source/IMG/vol4/vo04_ga07.jpg
Normal file
|
After Width: | Height: | Size: 166 KiB |
203
source/Main.py
@@ -8,27 +8,30 @@ import base64
|
||||
import psutil
|
||||
import ctypes
|
||||
import concurrent.futures
|
||||
|
||||
from PySide6 import QtWidgets, QtCore
|
||||
from PySide6.QtCore import Qt, QByteArray, QThread, Signal
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QWidget,
|
||||
QMessageBox,
|
||||
QProgressBar,
|
||||
QVBoxLayout,
|
||||
QLabel,
|
||||
QDialog,
|
||||
)
|
||||
from PySide6.QtGui import QIcon, QPixmap
|
||||
from PySide6.QtGui import QIcon
|
||||
from collections import deque
|
||||
from pic_data import img_data
|
||||
from GUI import Ui_mainwin
|
||||
|
||||
from PySide6.QtCore import ( Qt,
|
||||
Signal, QThread, QTimer)
|
||||
from PySide6.QtGui import (QIcon, QPixmap, )
|
||||
from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QMessageBox,
|
||||
QProgressBar, QVBoxLayout, QFileDialog, QDialog)
|
||||
|
||||
from Ui_install import Ui_MainWindows
|
||||
from animations import MultiStageAnimations
|
||||
import sys
|
||||
import os
|
||||
|
||||
def load_base64_image(base64_str):
|
||||
pixmap = QPixmap()
|
||||
pixmap.loadFromData(base64.b64decode(base64_str))
|
||||
return pixmap
|
||||
|
||||
# 配置信息
|
||||
app_data = {
|
||||
"APP_VERSION": "4.10.0.17496",
|
||||
"APP_NAME": "@FRAISEMOE Addons Installer",
|
||||
"APP_NAME": "@FRAISEMOE2 Addons Installer",
|
||||
"TEMP": "TEMP",
|
||||
"CACHE": "FRAISEMOE",
|
||||
"PLUGIN": "PLUGIN",
|
||||
@@ -59,15 +62,21 @@ app_data = {
|
||||
"install_path": "NEKOPARA Vol. 4/vol4adult.xp3",
|
||||
"plugin_path": "vol.4/vol4adult.xp3",
|
||||
},
|
||||
"NEKOPARA After": {
|
||||
"exe": "nekopara_after.exe",
|
||||
"hash": "eb26ff6850096a240af8340ba21c5c3232e90f29fb8191e24b6ce701acae0aa9",
|
||||
"install_path": "NEKOPARA After/afteradult.xp3",
|
||||
"plugin_path": "after/afteradult.xp3",
|
||||
"sig_path": "after/afteradult.xp3.sig"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# Base64解码
|
||||
def decode_base64(encoded_str):
|
||||
return base64.b64decode(encoded_str).decode("utf-8")
|
||||
|
||||
|
||||
# 全局变量
|
||||
APP_VERSION = app_data["APP_VERSION"]
|
||||
APP_NAME = app_data["APP_NAME"]
|
||||
TEMP = os.getenv(app_data["TEMP"])
|
||||
@@ -81,26 +90,29 @@ HASH_SIZE = 134217728
|
||||
PLUGIN_HASH = {game: info["hash"] for game, info in GAME_INFO.items()}
|
||||
PROCESS_INFO = {info["exe"]: game for game, info in GAME_INFO.items()}
|
||||
|
||||
|
||||
# 弹窗框架
|
||||
def msgbox_frame(title, text, buttons=QMessageBox.StandardButton.NoButton):
|
||||
msg_box = QMessageBox()
|
||||
msg_box.setWindowTitle(title)
|
||||
pixmap = QPixmap()
|
||||
pixmap.loadFromData(QByteArray(base64.b64decode(img_data["icon"])))
|
||||
icon = QIcon(pixmap)
|
||||
msg_box.setWindowIcon(icon)
|
||||
|
||||
# 设置弹窗图标
|
||||
icon_data = img_data.get("icon")
|
||||
if icon_data:
|
||||
pixmap = load_base64_image(icon_data)
|
||||
if not pixmap.isNull():
|
||||
msg_box.setWindowIcon(QIcon(pixmap))
|
||||
msg_box.setIconPixmap(pixmap.scaled(64, 64, Qt.KeepAspectRatio))
|
||||
else:
|
||||
msg_box.setIcon(QMessageBox.Information)
|
||||
|
||||
msg_box.setText(text)
|
||||
msg_box.setStandardButtons(buttons)
|
||||
return msg_box
|
||||
|
||||
|
||||
# 哈希值计算类
|
||||
class HashManager:
|
||||
def __init__(self, HASH_SIZE):
|
||||
self.HASH_SIZE = HASH_SIZE
|
||||
|
||||
# 哈希值计算
|
||||
def hash_calculate(self, file_path):
|
||||
sha256_hash = hashlib.sha256()
|
||||
with open(file_path, "rb") as f:
|
||||
@@ -108,7 +120,6 @@ class HashManager:
|
||||
sha256_hash.update(byte_block)
|
||||
return sha256_hash.hexdigest()
|
||||
|
||||
# 使用多线程优化哈希值计算
|
||||
def calculate_hashes_in_parallel(self, file_paths):
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
future_to_file = {
|
||||
@@ -129,17 +140,13 @@ class HashManager:
|
||||
msg_box.exec()
|
||||
return results
|
||||
|
||||
# 哈希值计算时的窗口
|
||||
def hash_pop_window(self):
|
||||
msg_box = msgbox_frame(f"通知 {APP_NAME}", "\n正在检验文件状态...\n")
|
||||
msg_box.show()
|
||||
QApplication.processEvents()
|
||||
return msg_box
|
||||
|
||||
# 下载前比对已有文件哈希值
|
||||
def cfg_pre_hash_compare(
|
||||
self, install_path, game_version, plugin_hash, installed_status
|
||||
):
|
||||
def cfg_pre_hash_compare(self, install_path, game_version, plugin_hash, installed_status):
|
||||
if not os.path.exists(install_path):
|
||||
installed_status[game_version] = False
|
||||
return
|
||||
@@ -157,7 +164,6 @@ class HashManager:
|
||||
else:
|
||||
installed_status[game_version] = True
|
||||
|
||||
# 下载完成后比对哈希值
|
||||
def cfg_after_hash_compare(self, install_paths, plugin_hash, installed_status):
|
||||
passed = True
|
||||
file_paths = [
|
||||
@@ -180,26 +186,23 @@ class HashManager:
|
||||
break
|
||||
return passed
|
||||
|
||||
|
||||
# 管理员权限检查类
|
||||
class AdminPrivileges:
|
||||
# 进程列表
|
||||
def __init__(self):
|
||||
self.required_exes = [
|
||||
"nekopara_vol1.exe",
|
||||
"nekopara_vol2.exe",
|
||||
"NEKOPARAvol3.exe",
|
||||
"nekopara_vol4.exe",
|
||||
"nekopara_after.exe",
|
||||
]
|
||||
|
||||
# 检查管理员权限
|
||||
def is_admin(self):
|
||||
try:
|
||||
return ctypes.windll.shell32.IsUserAnAdmin()
|
||||
except:
|
||||
return False
|
||||
|
||||
# 请求管理员权限
|
||||
def request_admin_privileges(self):
|
||||
if not self.is_admin():
|
||||
msg_box = msgbox_frame(
|
||||
@@ -230,7 +233,6 @@ class AdminPrivileges:
|
||||
msg_box.exec()
|
||||
sys.exit(1)
|
||||
|
||||
# 检查并终止进程
|
||||
def check_and_terminate_processes(self):
|
||||
for proc in psutil.process_iter(["pid", "name"]):
|
||||
if proc.info["name"] in self.required_exes:
|
||||
@@ -261,18 +263,16 @@ class AdminPrivileges:
|
||||
msg_box.exec()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# 下载线程类
|
||||
class DownloadThread(QThread):
|
||||
progress = Signal(int) # 进度信号
|
||||
finished = Signal(bool, str) # 完成信号
|
||||
progress = Signal(int)
|
||||
finished = Signal(bool, str)
|
||||
|
||||
def __init__(self, url, _7z_path, parent=None):
|
||||
super().__init__(parent)
|
||||
self.url = url # 下载地址
|
||||
self._7z_path = _7z_path # 7z文件路径
|
||||
self.url = url
|
||||
self._7z_path = _7z_path
|
||||
|
||||
# 下载线程运行
|
||||
def run(self):
|
||||
try:
|
||||
headers = {"User-Agent": UA}
|
||||
@@ -282,14 +282,13 @@ class DownloadThread(QThread):
|
||||
with open(self._7z_path, "wb") as f:
|
||||
for chunk in r.iter_content(chunk_size=BLOCK_SIZE):
|
||||
f.write(chunk)
|
||||
self.progress.emit(f.tell() * 100 // total_size) # 发送进度信号
|
||||
self.finished.emit(True, "") # 发送完成信号
|
||||
self.progress.emit(f.tell() * 100 // total_size)
|
||||
self.finished.emit(True, "")
|
||||
except requests.exceptions.RequestException as e:
|
||||
self.finished.emit(False, f"\n网络请求错误\n\n【错误信息】: {e}\n")
|
||||
except Exception as e:
|
||||
self.finished.emit(False, f"\n未知错误\n\n【错误信息】: {e}\n")
|
||||
|
||||
|
||||
# 下载进度窗口类
|
||||
class ProgressWindow(QDialog):
|
||||
def __init__(self, parent=None):
|
||||
@@ -297,12 +296,8 @@ class ProgressWindow(QDialog):
|
||||
self.setWindowTitle(f"下载进度 {APP_NAME}")
|
||||
self.resize(400, 100)
|
||||
self.progress_bar_max = 100
|
||||
self.setWindowFlags(
|
||||
self.windowFlags() & ~Qt.WindowCloseButtonHint
|
||||
) # 禁用关闭按钮
|
||||
self.setWindowFlags(
|
||||
self.windowFlags() & ~Qt.WindowSystemMenuHint
|
||||
) # 禁用系统菜单
|
||||
self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint)
|
||||
self.setWindowFlags(self.windowFlags() & ~Qt.WindowSystemMenuHint)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
self.progress_bar = QProgressBar()
|
||||
@@ -312,26 +307,39 @@ class ProgressWindow(QDialog):
|
||||
layout.addWidget(self.progress_bar)
|
||||
self.setLayout(layout)
|
||||
|
||||
# 设置进度条最大值
|
||||
def setmaxvalue(self, value):
|
||||
self.progress_bar_max = value
|
||||
self.progress_bar.setMaximum(value)
|
||||
|
||||
# 设置进度条值
|
||||
def setprogressbarval(self, value):
|
||||
self.progress_bar.setValue(value)
|
||||
if value == self.progress_bar_max: # 下载完成后关闭窗口
|
||||
QtCore.QTimer.singleShot(2000, self.close)
|
||||
|
||||
if value == self.progress_bar_max:
|
||||
QTimer.singleShot(2000, self.close)
|
||||
|
||||
# 主窗口类
|
||||
class MyWindow(QWidget, Ui_mainwin):
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
# 初始化UI (从Ui_install.py导入)
|
||||
self.ui = Ui_MainWindows()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
icon_data = img_data.get("icon")
|
||||
if icon_data:
|
||||
pixmap = load_base64_image(icon_data)
|
||||
self.setWindowIcon(QIcon(pixmap))
|
||||
|
||||
# 设置窗口标题为APP_NAME加版本号
|
||||
self.setWindowTitle(f"{APP_NAME} v{APP_VERSION}")
|
||||
|
||||
# 初始化动画系统 (从animations.py导入)
|
||||
self.animator = MultiStageAnimations(self.ui)
|
||||
|
||||
# 初始化功能变量
|
||||
self.selected_folder = ""
|
||||
self.installed_status = {f"NEKOPARA Vol.{i}": False for i in range(1, 5)}
|
||||
self.installed_status["NEKOPARA After"] = False # 添加After的状态
|
||||
self.download_queue = deque()
|
||||
self.current_download_thread = None
|
||||
self.hash_manager = HashManager(BLOCK_SIZE)
|
||||
@@ -340,6 +348,7 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
admin_privileges = AdminPrivileges()
|
||||
admin_privileges.request_admin_privileges()
|
||||
admin_privileges.check_and_terminate_processes()
|
||||
|
||||
# 创建缓存目录
|
||||
if not os.path.exists(PLUGIN):
|
||||
try:
|
||||
@@ -351,20 +360,28 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
f"\n无法创建缓存位置\n\n使用管理员身份运行或检查文件读写权限\n\n【错误信息】:{e}\n",
|
||||
)
|
||||
sys.exit(1)
|
||||
# 连接信号 & UI按钮
|
||||
self.startbtn.clicked.connect(self.file_dialog)
|
||||
self.exitbtn.clicked.connect(self.shutdown_app)
|
||||
|
||||
# 获取游戏安装路径
|
||||
# 连接信号 (使用Ui_install.py中的组件名称)
|
||||
self.ui.start_install_btn.clicked.connect(self.file_dialog)
|
||||
self.ui.exit_btn.clicked.connect(self.shutdown_app)
|
||||
|
||||
# 在窗口显示前设置初始状态
|
||||
self.animator.initialize()
|
||||
|
||||
# 窗口显示后延迟100ms启动动画
|
||||
QTimer.singleShot(100, self.start_animations)
|
||||
|
||||
def start_animations(self):
|
||||
self.animator.start_animations()
|
||||
|
||||
def get_install_paths(self):
|
||||
return {
|
||||
game: os.path.join(self.selected_folder, info["install_path"])
|
||||
for game, info in GAME_INFO.items()
|
||||
}
|
||||
|
||||
# 获取游戏目录
|
||||
def file_dialog(self):
|
||||
self.selected_folder = QtWidgets.QFileDialog.getExistingDirectory(
|
||||
self.selected_folder = QFileDialog.getExistingDirectory(
|
||||
self, f"选择游戏所在【上级目录】 {APP_NAME}"
|
||||
)
|
||||
if not self.selected_folder:
|
||||
@@ -374,23 +391,22 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
return
|
||||
self.download_action()
|
||||
|
||||
# 获取下载配置文件
|
||||
def get_download_url(self) -> dict:
|
||||
try:
|
||||
headers = {"User-Agent": UA}
|
||||
response = requests.get(CONFIG_URL, headers=headers, timeout=10)
|
||||
response.raise_for_status()
|
||||
config_data = response.json()
|
||||
if not all(f"vol.{i+1}.data" in config_data for i in range(4)):
|
||||
if not all(f"vol.{i+1}.data" in config_data for i in range(4)) or "after.data" not in config_data:
|
||||
raise ValueError("配置文件数据异常")
|
||||
return {
|
||||
f"vol{i+1}": config_data[f"vol.{i+1}.data"]["url"] for i in range(4)
|
||||
} | {
|
||||
"after": config_data["after.data"]["url"]
|
||||
}
|
||||
except requests.exceptions.RequestException as e:
|
||||
# 获取 HTTP 状态码
|
||||
status_code = e.response.status_code if e.response is not None else "未知"
|
||||
try:
|
||||
# 尝试从响应中解析 JSON 并提取 title 和 message
|
||||
error_response = e.response.json() if e.response else {}
|
||||
json_title = error_response.get("title", "无错误类型")
|
||||
json_message = error_response.get("message", "无附加错误信息")
|
||||
@@ -412,7 +428,6 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
)
|
||||
return {}
|
||||
|
||||
# 下载参数设置
|
||||
def download_setting(self, url, game_folder, game_version, _7z_path, plugin_path):
|
||||
game_exe = {
|
||||
game: os.path.join(
|
||||
@@ -420,7 +435,7 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
)
|
||||
for game, info in GAME_INFO.items()
|
||||
}
|
||||
# 判断游戏是否存在,不存在则跳过
|
||||
|
||||
if (
|
||||
game_version not in game_exe
|
||||
or not os.path.exists(game_exe[game_version])
|
||||
@@ -429,10 +444,10 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
self.installed_status[game_version] = False
|
||||
self.show_result()
|
||||
return
|
||||
# 下载时显示进度窗口
|
||||
|
||||
progress_window = ProgressWindow(self)
|
||||
progress_window.show()
|
||||
# 启用下载线程
|
||||
|
||||
self.current_download_thread = DownloadThread(url, _7z_path, self)
|
||||
self.current_download_thread.progress.connect(progress_window.setprogressbarval)
|
||||
self.current_download_thread.finished.connect(
|
||||
@@ -448,7 +463,6 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
)
|
||||
self.current_download_thread.start()
|
||||
|
||||
# 安装设置
|
||||
def install_setting(
|
||||
self,
|
||||
success,
|
||||
@@ -466,7 +480,18 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
QApplication.processEvents()
|
||||
with py7zr.SevenZipFile(_7z_path, mode="r") as archive:
|
||||
archive.extractall(path=PLUGIN)
|
||||
|
||||
# 创建游戏目录(如果不存在)
|
||||
os.makedirs(game_folder, exist_ok=True)
|
||||
|
||||
# 复制主文件
|
||||
shutil.copy(plugin_path, game_folder)
|
||||
|
||||
# 如果是After版本,还需要复制签名文件
|
||||
if game_version == "NEKOPARA After":
|
||||
sig_path = os.path.join(PLUGIN, GAME_INFO[game_version]["sig_path"])
|
||||
shutil.copy(sig_path, game_folder)
|
||||
|
||||
self.installed_status[game_version] = True
|
||||
QMessageBox.information(
|
||||
self, f"通知 {APP_NAME}", f"\n{game_version} 补丁已安装\n"
|
||||
@@ -487,7 +512,6 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
)
|
||||
self.next_download_task()
|
||||
|
||||
# 下载前比对已有文件哈希值
|
||||
def pre_hash_compare(self, install_path, game_version, plugin_hash):
|
||||
msg_box = self.hash_manager.hash_pop_window()
|
||||
self.hash_manager.cfg_pre_hash_compare(
|
||||
@@ -495,7 +519,6 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
)
|
||||
msg_box.close()
|
||||
|
||||
# 开始下载文件
|
||||
def download_action(self):
|
||||
install_paths = self.get_install_paths()
|
||||
for game_version, install_path in install_paths.items():
|
||||
@@ -508,6 +531,7 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
)
|
||||
return
|
||||
|
||||
# 处理1-4卷
|
||||
for i in range(1, 5):
|
||||
game_version = f"NEKOPARA Vol.{i}"
|
||||
if not self.installed_status[game_version]:
|
||||
@@ -521,19 +545,28 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
(url, game_folder, game_version, _7z_path, plugin_path)
|
||||
)
|
||||
|
||||
# 处理After
|
||||
game_version = "NEKOPARA After"
|
||||
if not self.installed_status[game_version]:
|
||||
url = config["after"]
|
||||
game_folder = os.path.join(self.selected_folder, "NEKOPARA After")
|
||||
_7z_path = os.path.join(PLUGIN, "after.7z")
|
||||
plugin_path = os.path.join(
|
||||
PLUGIN, GAME_INFO[game_version]["plugin_path"]
|
||||
)
|
||||
self.download_queue.append(
|
||||
(url, game_folder, game_version, _7z_path, plugin_path)
|
||||
)
|
||||
|
||||
self.next_download_task()
|
||||
|
||||
# 开始下载队列中的下一个任务
|
||||
def next_download_task(self):
|
||||
if not self.download_queue:
|
||||
self.after_hash_compare(PLUGIN_HASH)
|
||||
return
|
||||
url, game_folder, game_version, _7z_path, plugin_path = (
|
||||
self.download_queue.popleft()
|
||||
)
|
||||
url, game_folder, game_version, _7z_path, plugin_path = self.download_queue.popleft()
|
||||
self.download_setting(url, game_folder, game_version, _7z_path, plugin_path)
|
||||
|
||||
# 下载完成后比对哈希值
|
||||
def after_hash_compare(self, plugin_hash):
|
||||
msg_box = self.hash_manager.hash_pop_window()
|
||||
result = self.hash_manager.cfg_after_hash_compare(
|
||||
@@ -543,7 +576,6 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
self.show_result()
|
||||
return result
|
||||
|
||||
# 显示最终安装结果
|
||||
def show_result(self):
|
||||
installed_version = "\n".join(
|
||||
[i for i in self.installed_status if self.installed_status[i]]
|
||||
@@ -558,11 +590,9 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
f"安装成功的版本:\n{installed_version}\n尚未持有或未使用本工具安装补丁的版本:\n{failed_ver}\n",
|
||||
)
|
||||
|
||||
# 关闭程序-窗口
|
||||
def closeEvent(self, event):
|
||||
self.shutdown_app(event)
|
||||
|
||||
# 关闭程序-按钮
|
||||
def shutdown_app(self, event=None):
|
||||
reply = QMessageBox.question(
|
||||
self,
|
||||
@@ -609,9 +639,8 @@ class MyWindow(QWidget, Ui_mainwin):
|
||||
if event:
|
||||
event.ignore()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication([])
|
||||
window = MyWindow()
|
||||
window = MainWindow()
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
||||
169
source/Ui_install.py
Normal file
@@ -0,0 +1,169 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'install.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.9.1
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
from pic_data import img_data
|
||||
from PySide6.QtGui import QPixmap
|
||||
import base64
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
|
||||
QCursor, QFont, QFontDatabase, QGradient,
|
||||
QIcon, QImage, QKeySequence, QLinearGradient,
|
||||
QPainter, QPalette, QPixmap, QRadialGradient,
|
||||
QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QMenu,
|
||||
QMenuBar, QPushButton, QSizePolicy, QWidget)
|
||||
def load_base64_image(base64_str):
|
||||
pixmap = QPixmap()
|
||||
pixmap.loadFromData(base64.b64decode(base64_str))
|
||||
return pixmap
|
||||
|
||||
|
||||
class Ui_MainWindows(object):
|
||||
def setupUi(self, MainWindows):
|
||||
if not MainWindows.objectName():
|
||||
MainWindows.setObjectName(u"MainWindows")
|
||||
MainWindows.setEnabled(True)
|
||||
MainWindows.resize(1024, 576)
|
||||
MainWindows.setMinimumSize(QSize(1024, 576))
|
||||
MainWindows.setMaximumSize(QSize(1024, 576))
|
||||
MainWindows.setMouseTracking(False)
|
||||
MainWindows.setTabletTracking(False)
|
||||
MainWindows.setAcceptDrops(True)
|
||||
MainWindows.setAutoFillBackground(True)
|
||||
MainWindows.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
|
||||
MainWindows.setAnimated(True)
|
||||
MainWindows.setDocumentMode(False)
|
||||
MainWindows.setDockNestingEnabled(False)
|
||||
self.action_2 = QAction(MainWindows)
|
||||
self.action_2.setObjectName(u"action_2")
|
||||
self.centralwidget = QWidget(MainWindows)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.centralwidget.setAutoFillBackground(True)
|
||||
self.loadbg = QLabel(self.centralwidget)
|
||||
self.loadbg.setObjectName(u"loadbg")
|
||||
self.loadbg.setGeometry(QRect(0, 0, 1031, 561))
|
||||
self.loadbg.setPixmap(load_base64_image(img_data["loadbg"]))
|
||||
self.loadbg.setScaledContents(True)
|
||||
self.vol1bg = QLabel(self.centralwidget)
|
||||
self.vol1bg.setObjectName(u"vol1bg")
|
||||
self.vol1bg.setGeometry(QRect(0, 120, 93, 64))
|
||||
self.vol1bg.setPixmap(load_base64_image(img_data["vol1"]))
|
||||
self.vol1bg.setScaledContents(True)
|
||||
self.vol2bg = QLabel(self.centralwidget)
|
||||
self.vol2bg.setObjectName(u"vol2bg")
|
||||
self.vol2bg.setGeometry(QRect(0, 180, 93, 64))
|
||||
self.vol2bg.setPixmap(load_base64_image(img_data["vol2"]))
|
||||
self.vol2bg.setScaledContents(True)
|
||||
self.vol3bg = QLabel(self.centralwidget)
|
||||
self.vol3bg.setObjectName(u"vol3bg")
|
||||
self.vol3bg.setGeometry(QRect(0, 240, 93, 64))
|
||||
self.vol3bg.setPixmap(load_base64_image(img_data["vol3"]))
|
||||
self.vol3bg.setScaledContents(True)
|
||||
self.vol4bg = QLabel(self.centralwidget)
|
||||
self.vol4bg.setObjectName(u"vol4bg")
|
||||
self.vol4bg.setGeometry(QRect(0, 300, 93, 64))
|
||||
self.vol4bg.setPixmap(load_base64_image(img_data["vol4"]))
|
||||
self.vol4bg.setScaledContents(True)
|
||||
self.afterbg = QLabel(self.centralwidget)
|
||||
self.afterbg.setObjectName(u"afterbg")
|
||||
self.afterbg.setGeometry(QRect(0, 360, 93, 64))
|
||||
self.afterbg.setPixmap(load_base64_image(img_data["after"]))
|
||||
self.afterbg.setScaledContents(True)
|
||||
self.Mainbg = QLabel(self.centralwidget)
|
||||
self.Mainbg.setObjectName(u"Mainbg")
|
||||
self.Mainbg.setGeometry(QRect(0, 0, 1031, 561))
|
||||
self.Mainbg.setPixmap(load_base64_image(img_data["Mainbg"]))
|
||||
self.Mainbg.setScaledContents(True)
|
||||
self.start_install_btn = QPushButton(self.centralwidget)
|
||||
self.start_install_btn.setObjectName(u"start_install_btn")
|
||||
self.start_install_btn.setEnabled(True)
|
||||
self.start_install_btn.setGeometry(QRect(780, 250, 191, 91))
|
||||
self.start_install_btn.setAutoFillBackground(False)
|
||||
start_install_icon = QIcon()
|
||||
start_install_pixmap = load_base64_image(img_data["start_install_btn"])
|
||||
if not start_install_pixmap.isNull():
|
||||
start_install_icon.addPixmap(start_install_pixmap)
|
||||
self.start_install_btn.setIcon(start_install_icon)
|
||||
self.start_install_btn.setIcon(start_install_icon)
|
||||
self.start_install_btn.setIconSize(QSize(189, 110))
|
||||
self.start_install_btn.setCheckable(False)
|
||||
self.start_install_btn.setAutoRepeat(False)
|
||||
self.start_install_btn.setAutoDefault(False)
|
||||
self.start_install_btn.setFlat(True)
|
||||
self.exit_btn = QPushButton(self.centralwidget)
|
||||
self.exit_btn.setObjectName(u"exit_btn")
|
||||
self.exit_btn.setEnabled(True)
|
||||
self.exit_btn.setGeometry(QRect(780, 340, 191, 91))
|
||||
self.exit_btn.setAutoFillBackground(False)
|
||||
exit_icon = QIcon()
|
||||
exit_pixmap = load_base64_image(img_data["exit_btn"])
|
||||
if not exit_pixmap.isNull():
|
||||
exit_icon.addPixmap(exit_pixmap)
|
||||
self.exit_btn.setIcon(exit_icon)
|
||||
self.exit_btn.setIcon(exit_icon)
|
||||
self.exit_btn.setIconSize(QSize(189, 110))
|
||||
self.exit_btn.setCheckable(False)
|
||||
self.exit_btn.setFlat(True)
|
||||
self.menubg = QLabel(self.centralwidget)
|
||||
self.menubg.setObjectName(u"menubg")
|
||||
self.menubg.setGeometry(QRect(710, 0, 321, 561))
|
||||
self.menubg.setPixmap(load_base64_image(img_data["menubg"]))
|
||||
self.menubg.setScaledContents(True)
|
||||
MainWindows.setCentralWidget(self.centralwidget)
|
||||
self.loadbg.raise_()
|
||||
self.vol1bg.raise_()
|
||||
self.vol2bg.raise_()
|
||||
self.vol3bg.raise_()
|
||||
self.vol4bg.raise_()
|
||||
self.afterbg.raise_()
|
||||
self.Mainbg.raise_()
|
||||
self.menubg.raise_()
|
||||
self.start_install_btn.raise_()
|
||||
self.exit_btn.raise_()
|
||||
self.menubar = QMenuBar(MainWindows)
|
||||
self.menubar.setObjectName(u"menubar")
|
||||
self.menubar.setGeometry(QRect(0, 0, 1024, 21))
|
||||
self.menu = QMenu(self.menubar)
|
||||
self.menu.setObjectName(u"menu")
|
||||
self.menu_2 = QMenu(self.menubar)
|
||||
self.menu_2.setObjectName(u"menu_2")
|
||||
MainWindows.setMenuBar(self.menubar)
|
||||
|
||||
self.menubar.addAction(self.menu.menuAction())
|
||||
self.menubar.addAction(self.menu_2.menuAction())
|
||||
self.menu.addSeparator()
|
||||
self.menu.addAction(self.action_2)
|
||||
|
||||
self.retranslateUi(MainWindows)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindows)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindows):
|
||||
MainWindows.setWindowTitle(QCoreApplication.translate("MainWindows", u" UI Test", None))
|
||||
self.action_2.setText(QCoreApplication.translate("MainWindows", u"\u68c0\u67e5\u66f4\u65b0(\u672a\u5b8c\u6210)", None))
|
||||
self.loadbg.setText("")
|
||||
self.vol1bg.setText("")
|
||||
self.vol2bg.setText("")
|
||||
self.vol3bg.setText("")
|
||||
self.vol4bg.setText("")
|
||||
self.afterbg.setText("")
|
||||
self.Mainbg.setText("")
|
||||
#if QT_CONFIG(accessibility)
|
||||
self.start_install_btn.setAccessibleDescription("")
|
||||
#endif // QT_CONFIG(accessibility)
|
||||
self.start_install_btn.setText("")
|
||||
self.exit_btn.setText("")
|
||||
self.menubg.setText("")
|
||||
self.menu.setTitle(QCoreApplication.translate("MainWindows", u"\u8bbe\u7f6e", None))
|
||||
self.menu_2.setTitle(QCoreApplication.translate("MainWindows", u"\u5173\u4e8e", None))
|
||||
# retranslateUi
|
||||
|
||||
168
source/animations.py
Normal file
@@ -0,0 +1,168 @@
|
||||
from PySide6.QtCore import (QPropertyAnimation, QParallelAnimationGroup,
|
||||
QPoint, QEasingCurve, QTimer)
|
||||
from PySide6.QtWidgets import QGraphicsOpacityEffect
|
||||
|
||||
class MultiStageAnimations:
|
||||
def __init__(self, ui):
|
||||
self.ui = ui
|
||||
# 获取画布尺寸
|
||||
self.canvas_width = ui.centralwidget.width()
|
||||
self.canvas_height = ui.centralwidget.height()
|
||||
|
||||
# 动画时序配置
|
||||
self.animation_config = {
|
||||
"logo": {
|
||||
"delay_after": 2800
|
||||
},
|
||||
"mainbg": {
|
||||
"delay_after": 500
|
||||
}
|
||||
}
|
||||
|
||||
# 第一阶段:Logo动画配置
|
||||
self.logo_widgets = [
|
||||
{"widget": ui.vol1bg, "delay": 0, "duration": 500, "end_pos": QPoint(0, 120)},
|
||||
{"widget": ui.vol2bg, "delay": 80, "duration": 500, "end_pos": QPoint(0, 180)},
|
||||
{"widget": ui.vol3bg, "delay": 160, "duration": 500, "end_pos": QPoint(0, 240)},
|
||||
{"widget": ui.vol4bg, "delay": 240, "duration": 500, "end_pos": QPoint(0, 300)},
|
||||
{"widget": ui.afterbg, "delay": 320, "duration": 500, "end_pos": QPoint(0, 360)}
|
||||
]
|
||||
|
||||
# 第二阶段:菜单元素
|
||||
self.menu_widgets = [
|
||||
{"widget": ui.menubg, "end_pos": QPoint(710, 0), "duration": 600},
|
||||
{"widget": ui.start_install_btn, "end_pos": QPoint(780, 250), "duration": 600},
|
||||
{"widget": ui.exit_btn, "end_pos": QPoint(780, 340), "duration": 600}
|
||||
]
|
||||
|
||||
self.animations = []
|
||||
self.timers = []
|
||||
def initialize(self):
|
||||
"""初始化所有组件状态"""
|
||||
# 设置Mainbg初始状态
|
||||
effect = QGraphicsOpacityEffect(self.ui.Mainbg)
|
||||
effect.setOpacity(0)
|
||||
self.ui.Mainbg.setGraphicsEffect(effect)
|
||||
|
||||
# 初始化Logo位置(移到左侧外)
|
||||
for item in self.logo_widgets:
|
||||
widget = item["widget"]
|
||||
effect = QGraphicsOpacityEffect(widget)
|
||||
effect.setOpacity(0)
|
||||
widget.setGraphicsEffect(effect)
|
||||
widget.move(-widget.width(), item["end_pos"].y())
|
||||
widget.show()
|
||||
print("初始化支持栏动画")
|
||||
|
||||
# 初始化菜单元素(底部外)
|
||||
for item in self.menu_widgets:
|
||||
widget = item["widget"]
|
||||
effect = QGraphicsOpacityEffect(widget)
|
||||
effect.setOpacity(0)
|
||||
widget.setGraphicsEffect(effect)
|
||||
widget.move(widget.x(), self.canvas_height + 100)
|
||||
widget.show()
|
||||
|
||||
def start_logo_animations(self):
|
||||
"""启动Logo动画序列"""
|
||||
for item in self.logo_widgets:
|
||||
timer = QTimer()
|
||||
timer.setSingleShot(True)
|
||||
timer.timeout.connect(
|
||||
lambda w=item["widget"], d=item["duration"], pos=item["end_pos"]:
|
||||
self.animate_logo(w, pos, d)
|
||||
)
|
||||
timer.start(item["delay"])
|
||||
self.timers.append(timer)
|
||||
|
||||
def animate_logo(self, widget, end_pos, duration):
|
||||
"""执行单个Logo动画"""
|
||||
anim_group = QParallelAnimationGroup()
|
||||
|
||||
# 位置动画
|
||||
pos_anim = QPropertyAnimation(widget, b"pos")
|
||||
pos_anim.setDuration(duration)
|
||||
pos_anim.setStartValue(QPoint(-widget.width(), end_pos.y()))
|
||||
pos_anim.setEndValue(end_pos)
|
||||
pos_anim.setEasingCurve(QEasingCurve.OutBack)
|
||||
|
||||
# 透明度动画
|
||||
opacity_anim = QPropertyAnimation(widget.graphicsEffect(), b"opacity")
|
||||
opacity_anim.setDuration(duration)
|
||||
opacity_anim.setStartValue(0)
|
||||
opacity_anim.setEndValue(1)
|
||||
|
||||
anim_group.addAnimation(pos_anim)
|
||||
anim_group.addAnimation(opacity_anim)
|
||||
|
||||
# 最后一个Logo动画完成后添加延迟
|
||||
if widget == self.logo_widgets[-1]["widget"]:
|
||||
anim_group.finished.connect(
|
||||
lambda: QTimer.singleShot(
|
||||
self.animation_config["logo"]["delay_after"],
|
||||
self.start_mainbg_animation
|
||||
)
|
||||
)
|
||||
|
||||
anim_group.start()
|
||||
self.animations.append(anim_group)
|
||||
|
||||
def start_mainbg_animation(self):
|
||||
"""启动主背景淡入动画"""
|
||||
main_anim = QPropertyAnimation(self.ui.Mainbg.graphicsEffect(), b"opacity")
|
||||
main_anim.setDuration(800)
|
||||
main_anim.setStartValue(0)
|
||||
main_anim.setEndValue(1)
|
||||
main_anim.finished.connect(self.start_menu_animations)
|
||||
main_anim.start()
|
||||
self.animations.append(main_anim)
|
||||
|
||||
def start_mainbg_animation(self):
|
||||
"""启动主背景淡入动画(带延迟)"""
|
||||
main_anim = QPropertyAnimation(self.ui.Mainbg.graphicsEffect(), b"opacity")
|
||||
main_anim.setDuration(800)
|
||||
main_anim.setStartValue(0)
|
||||
main_anim.setEndValue(1)
|
||||
main_anim.finished.connect(
|
||||
lambda: QTimer.singleShot(
|
||||
self.animation_config["mainbg"]["delay_after"],
|
||||
self.start_menu_animations
|
||||
)
|
||||
)
|
||||
main_anim.start()
|
||||
self.animations.append(main_anim)
|
||||
def start_menu_animations(self):
|
||||
"""启动菜单动画(从下往上)"""
|
||||
for item in self.menu_widgets:
|
||||
anim_group = QParallelAnimationGroup()
|
||||
|
||||
# 位置动画(从下往上)
|
||||
pos_anim = QPropertyAnimation(item["widget"], b"pos")
|
||||
pos_anim.setDuration(item["duration"])
|
||||
pos_anim.setStartValue(QPoint(item["end_pos"].x(), self.canvas_height + 100))
|
||||
pos_anim.setEndValue(item["end_pos"])
|
||||
pos_anim.setEasingCurve(QEasingCurve.OutBack)
|
||||
|
||||
# 透明度动画
|
||||
opacity_anim = QPropertyAnimation(item["widget"].graphicsEffect(), b"opacity")
|
||||
opacity_anim.setDuration(item["duration"])
|
||||
opacity_anim.setStartValue(0)
|
||||
opacity_anim.setEndValue(1)
|
||||
|
||||
anim_group.addAnimation(pos_anim)
|
||||
anim_group.addAnimation(opacity_anim)
|
||||
anim_group.start()
|
||||
self.animations.append(anim_group)
|
||||
def start_animations(self):
|
||||
"""启动完整动画序列"""
|
||||
self.clear_animations()
|
||||
self.start_logo_animations()
|
||||
|
||||
def clear_animations(self):
|
||||
"""清理所有动画资源"""
|
||||
for timer in self.timers:
|
||||
timer.stop()
|
||||
for anim in self.animations:
|
||||
anim.stop()
|
||||
self.timers.clear()
|
||||
self.animations.clear()
|
||||
@@ -1,45 +0,0 @@
|
||||
# UTF-8
|
||||
#
|
||||
# For more details about fixed file info 'ffi' see:
|
||||
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
|
||||
VSVersionInfo(
|
||||
ffi=FixedFileInfo(
|
||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||
# Set not needed items to zero 0.
|
||||
filevers=(4, 9, 0, 17411),
|
||||
prodvers=(4, 9, 0, 17411),
|
||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||
mask=0x3f,
|
||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||
flags=0x0,
|
||||
# The operating system for which this file was designed.
|
||||
# 0x4 - NT and there is no need to change it.
|
||||
OS=0x40004,
|
||||
# The general type of file.
|
||||
# 0x1 - the file is an application.
|
||||
fileType=0x1,
|
||||
# The function of the file.
|
||||
# 0x0 - the function is not defined for this fileType
|
||||
subtype=0x0,
|
||||
# Creation date and time stamp.
|
||||
date=(0, 0)
|
||||
),
|
||||
kids=[
|
||||
StringFileInfo(
|
||||
[
|
||||
StringTable(
|
||||
'040904b0',
|
||||
[StringStruct('CompanyName', ''),
|
||||
StringStruct('FileDescription', 'FRAISEMOE Addons Installer'),
|
||||
StringStruct('FileVersion', '4.9.0.17411'),
|
||||
StringStruct('InternalName', 'FRAISEMOE Addons Installer'),
|
||||
StringStruct('LegalCopyright', ''),
|
||||
StringStruct('OriginalFilename', ''),
|
||||
StringStruct('ProductName', 'FRAISEMOE Addons Installer'),
|
||||
StringStruct('ProductVersion', '4.9.0.17411'),
|
||||
StringStruct('SquirrelAwareVersion', '1'),
|
||||
StringStruct('', '')])
|
||||
]),
|
||||
VarFileInfo([VarStruct('Translation', [2052, 1200])])
|
||||
]
|
||||
)
|
||||
BIN
source/icon.ico
Normal file
|
After Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 566 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 20 KiB |
333
source/install.ui
Normal file
@@ -0,0 +1,333 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindows</class>
|
||||
<widget class="QMainWindow" name="MainWindows">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1024</width>
|
||||
<height>576</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>1024</width>
|
||||
<height>576</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1024</width>
|
||||
<height>576</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tabletTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string> UI Test</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="documentMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dockNestingEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QLabel" name="loadbg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1031</width>
|
||||
<height>561</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/BG/bg2.jpg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="vol1bg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>120</y>
|
||||
<width>93</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/LOGO/vo01_logo.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="vol2bg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>180</y>
|
||||
<width>93</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/LOGO/vo02_logo.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="vol3bg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>240</y>
|
||||
<width>93</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/LOGO/vo03_logo.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="vol4bg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>300</y>
|
||||
<width>93</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/LOGO/vo04_logo.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="afterbg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>360</y>
|
||||
<width>93</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/LOGO/voaf_logo.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="Mainbg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1031</width>
|
||||
<height>561</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/BG/bg3.jpg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="start_install_btn">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>780</x>
|
||||
<y>250</y>
|
||||
<width>191</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>IMG/BTN/start_install.bmp</normaloff>IMG/BTN/start_install.bmp</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>189</width>
|
||||
<height>110</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="autoRepeat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="exit_btn">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>780</x>
|
||||
<y>340</y>
|
||||
<width>191</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>IMG/BTN/exit.bmp</normaloff>IMG/BTN/exit.bmp</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>189</width>
|
||||
<height>110</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="menubg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>710</x>
|
||||
<y>0</y>
|
||||
<width>321</width>
|
||||
<height>561</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>IMG/BG/menubg.jpg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>loadbg</zorder>
|
||||
<zorder>vol1bg</zorder>
|
||||
<zorder>vol2bg</zorder>
|
||||
<zorder>vol3bg</zorder>
|
||||
<zorder>vol4bg</zorder>
|
||||
<zorder>afterbg</zorder>
|
||||
<zorder>Mainbg</zorder>
|
||||
<zorder>menubg</zorder>
|
||||
<zorder>start_install_btn</zorder>
|
||||
<zorder>exit_btn</zorder>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1024</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu">
|
||||
<property name="title">
|
||||
<string>设置</string>
|
||||
</property>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_2"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_2">
|
||||
<property name="title">
|
||||
<string>关于</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menu"/>
|
||||
<addaction name="menu_2"/>
|
||||
</widget>
|
||||
<action name="action_2">
|
||||
<property name="text">
|
||||
<string>update - sd</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
8419
source/nuitka-crash-report.xml
Normal file
19
source/popup.ui
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>480</width>
|
||||
<height>270</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||