#!/usr/bin/env python3 # 本来是用C++写的,但在非deepin/UOS编译/运行就是下载不了https文件,只能用python重写 ######################################################################### # 作者:gfdgd xi # 版本:2.4.0 # 感谢:感谢 deepin-wine 团队,提供了 deepin-wine 给大家使用,让我能做这个程序 # 基于 Python3 的 PyQt5 构建 ######################################################################### ################# # 引入所需的库 ################# import os import shutil import random import sys import json import subprocess import traceback import requests import webbrowser programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string sys.path.append(f"{programPath}/../") from Model import * from PyQt5 import QtCore, QtGui, QtWidgets programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string # UI 布局(自动生成) class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(693, 404) self.centralWidget = QtWidgets.QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralWidget) self.verticalLayout_2.setContentsMargins(11, 11, 11, 11) self.verticalLayout_2.setSpacing(6) self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setSpacing(6) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.localWineList = QtWidgets.QListView(self.centralWidget) self.localWineList.setObjectName("localWineList") self.horizontalLayout_2.addWidget(self.localWineList) self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setSpacing(6) self.verticalLayout.setObjectName("verticalLayout") spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) self.addButton = QtWidgets.QPushButton(self.centralWidget) self.addButton.setObjectName("addButton") self.verticalLayout.addWidget(self.addButton) self.delButton = QtWidgets.QPushButton(self.centralWidget) self.delButton.setObjectName("delButton") self.verticalLayout.addWidget(self.delButton) spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem1) self.horizontalLayout_2.addLayout(self.verticalLayout) self.internetWineList = QtWidgets.QListView(self.centralWidget) self.internetWineList.setObjectName("internetWineList") self.horizontalLayout_2.addWidget(self.internetWineList) self.verticalLayout_2.addLayout(self.horizontalLayout_2) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setSpacing(6) self.horizontalLayout.setObjectName("horizontalLayout") self.unzip = QtWidgets.QCheckBox(self.centralWidget) self.unzip.setObjectName("unzip") self.horizontalLayout.addWidget(self.unzip) self.deleteZip = QtWidgets.QCheckBox(self.centralWidget) self.deleteZip.setChecked(True) self.deleteZip.setTristate(False) self.deleteZip.setObjectName("deleteZip") self.m_recommendWine = QtWidgets.QCheckBox(self.centralWidget) self.m_recommendWine.setChecked(True) self.m_recommendWine.setObjectName("recommendWine") self.horizontalLayout.addWidget(self.m_recommendWine) self.addOtherWine = QtWidgets.QPushButton(self.centralWidget) self.downloadWineFromCloudDisk = QtWidgets.QPushButton(self.centralWidget) self.horizontalLayout.addWidget(self.downloadWineFromCloudDisk) self.horizontalLayout.addWidget(self.addOtherWine) spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.verticalLayout_2.addLayout(self.horizontalLayout) MainWindow.setCentralWidget(self.centralWidget) # 菜单栏 _translate = QtCore.QCoreApplication.translate self.menu = MainWindow.menuBar() self.changeSources = self.menu.addMenu(_translate("MainWindow", "更换源")) self.gitlinkAction = QtWidgets.QAction(_translate("MainWindow", "Gitee 源(推荐)")) self.kgithubAction = QtWidgets.QAction(_translate("MainWindow", "Sourceforge 源")) self.ipv6Action = QtWidgets.QAction(_translate("MainWindow", "默认源")) self.githubAction = QtWidgets.QAction(_translate("MainWindow", "Github 源(国内访问不稳定)")) self.localAction = QtWidgets.QAction(_translate("MainWindow", "本地测试源(127.0.0.1)")) self.changeSources.addAction(self.ipv6Action) self.changeSources.addAction(self.kgithubAction) self.changeSources.addAction(self.gitlinkAction) self.changeSources.addAction(self.githubAction) self.changeSources.addAction(self.localAction) for i in [self.gitlinkAction, self.ipv6Action, self.localAction, self.kgithubAction, self.githubAction]: i.setCheckable(True) self.ipv6Action.setChecked(True) self.changeSourcesGroup = QtWidgets.QActionGroup(MainWindow) self.changeSourcesGroup.addAction(self.gitlinkAction) self.changeSourcesGroup.addAction(self.kgithubAction) self.changeSourcesGroup.addAction(self.ipv6Action) self.changeSourcesGroup.addAction(self.githubAction) self.changeSourcesGroup.addAction(self.localAction) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "下载 Wine")) self.addButton.setText(_translate("MainWindow", "<<")) self.delButton.setText(_translate("MainWindow", ">>")) self.unzip.setText(_translate("MainWindow", "不解压Wine资源文件")) self.deleteZip.setText(_translate("MainWindow", "删除下载的资源包,只解压保留(两个选项都选相互抵消)")) self.addOtherWine.setText(_translate("MainWindow", "导入 Wine 7z 包")) self.downloadWineFromCloudDisk.setText(_translate("MainWindow", "从网盘下载 Wine")) self.m_recommendWine.setText(_translate("MainWindow", "隐藏本机不可用 Wine")) def ReadLocalInformation(): try: global localJsonList file = open(f"{programPath}/winelist.json", "r") localJsonList = json.loads(file.read()) nmodel = QtGui.QStandardItemModel(window) for i in localJsonList: item = QtGui.QStandardItem(i) nmodel.appendRow(item) ui.localWineList.setModel(nmodel) file.close() except: print("新建空列表") try: with open(f"{programPath}/winelist.json", "w") as file: file.write("[]") except: traceback.print_exc() QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc()) def InstallOtherWine(): path = QtWidgets.QFileDialog.getOpenFileName(window, "选择 Wine 运行器 Wine 7z 包", os.getenv("~"), "Wine 运行器 Wine 7z 包(*.7z);;全部文件(*.*)") if path[0] == "" or not path[1]: return try: # 写入配置文件 rfile = open(f"{programPath}/winelist.json", "r") list = json.loads(rfile.read()) rfile.close() name = os.path.splitext(os.path.basename(path[0]))[0] removeSymbol = ["(", ")", "(", ")", " ", "!", "@", "#", "$", "%", "^", "&", "*", "=", "[", "]", "{", "}", "\\", "/", "|", "?", "<", ">", "·", "「", ";", ":", ":", "?", "《", "》", ",", "。", ",", ".", "`", "~", "~", "、"] for i in removeSymbol: name.replace(i, "") unpackPath = f"{programPath}/{name}" shellCommand = f"""mkdir -p \"{unpackPath}\" 7z x -y \"{path[0]}\" -o\"{unpackPath}\" """ shellFile = open("/tmp/depein-wine-runner-wine-install.sh", "w") shellFile.write(shellCommand) shellFile.close() OpenTerminal("bash /tmp/depein-wine-runner-wine-install.sh") # C++ 版注释:不直接用 readwrite 是因为不能覆盖写入 file = open(f"{programPath}/winelist.json", "w") list.append(name) file.write(json.dumps(list)) file.close() except: traceback.print_exc() QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc()) ReadLocalInformation() def ChangeSources(): global urlSources global internetWineSource sources = [ui.ipv6Action, ui.kgithubAction, ui.gitlinkAction, ui.githubAction, ui.localAction] for i in range(0, len(sources)): if sources[i].isChecked(): urlSources = internetWineSourceList[i] internetWineSource = internetWineSourceList[i] # 读取信息 ReadLocalInformation() ReadInternetInformation() break print(urlSources) class GetInfo(): arch = subprocess.getoutput("dpkg --print-architecture").replace("\n", "").replace(" ", "") isBinfmt = os.path.exists("/proc/sys/fs/binfmt_misc") isBox64 = not os.system("which box64 > /dev/null") >> 8 or not os.system("which spark-box64 > /dev/null") >> 8 isBox86 = not os.system("which box86 > /dev/null") >> 8 or not os.system("which spark-box86 > /dev/null") >> 8 isLat = not os.system("which lat-i386-static > /dev/null") >> 8 or not os.system("which latx-i386 > /dev/null") >> 8 isLati386Runtime = os.path.exists("/usr/gnemul/latx-i386") or os.path.exists("/usr/gnemul/lat-i386") isLatamd64Runtime = os.path.exists("/usr/gnemul/latx-x86_64") or os.path.exists("/usr/gnemul/lat-x86_64") isQemuUseri386Runtime = os.path.exists("/usr/lib/i386-linux-gnu/ld-linux.so.2") isQemuUseramd64Runtime = os.path.exists("/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2") isQemuUser = not os.system("which qemu-i386-static > /dev/null") >> 8 and (not "amd64" in arch) and (not "i386" in arch) pageSize = subprocess.getoutput("getconf PAGESIZE").replace(" ", "").replace("\n", "") is4kPageSize = (pageSize == "4096") is8kPageSize = (pageSize == "8096") is16kPageSize = (pageSize == "16192") is32kPageSize = (pageSize == "32384") is64kPageSize = (pageSize == "64768") isLoongarch = (arch == "loong64") or (arch == "loongarch64") isProot = os.path.exists("/storage") isAndroid = os.path.exists("/data") isTermux = os.path.exists("/data") glibcVersion = "2.28" def __init__(self): self.getGlibcVersion() def getGlibcVersion(self): version = None glibcPath = "" glibcPathList = [ "/usr/lib/i386-linux-gnu/ld-linux.so.2", "/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", "/usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3", "/usr/lib/arm-linux-gnueabi/ld-linux.so.3", "/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1", "/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1", "/usr/lib/riscv64-linux-gnu/ld-linux-riscv64-lp64d.so.1", "/usr/lib/mips64el-linux-gnuabi64/ld.so.1", "/usr/lib/powerpc64le-linux-gnu/ld64.so.2", "/usr/lib/loongarch64-linux-gnu/ld-linux-loongarch-lp64d.so.1", "/usr/lib/loongarch64-linux-gnu/ld.so.1", "/usr/lib/ld-linux.so.2", "/usr/lib/ld-linux-x86-64.so.2", "/usr/lib/ld-linux-armhf.so.3", "/usr/lib/ld-linux.so.3", "/usr/lib/ld-linux-aarch64.so.1", "/usr/lib/ld-linux-aarch64.so.1", "/usr/lib/ld-linux-riscv64-lp64d.so.1", "/usr/lib/ld.so.1", "/usr/lib/ld64.so.2", "/usr/lib/ld-linux-loongarch-lp64d.so.1", "/usr/lib64/ld.so.1", "/usr/lib64/ld-linux.so.2", "/usr/lib64/ld-linux-x86-64.so.2", "/usr/lib64/ld-linux-armhf.so.3", "/usr/lib64/ld-linux.so.3", "/usr/lib64/ld-linux-aarch64.so.1", "/usr/lib64/ld-linux-aarch64.so.1", "/usr/lib64/ld-linux-riscv64-lp64d.so.1", "/usr/lib64/ld.so.1", "/usr/lib64/ld64.so.2", "/usr/lib64/ld-linux-loongarch-lp64d.so.1", "/usr/lib64/ld.so.1" ] for i in glibcPathList: if (os.path.exists(i)): glibcPath = i break if glibcPath != "": glibcStr = subprocess.getoutput("strings " + glibcPath + " | grep GLIBC_") newestVersion = "1.0" for i in glibcStr.splitlines(): i = i.replace("GLIBC_", "") # 判断是不是版本号行 try: int(i[0]) except: # 非版本号行 continue if (self.compareVersion(newestVersion, i) == -1): newestVersion = i version = newestVersion if (version == None): version = "2.28" # 默认值 self.glibcVersion = version return version def compareVersion(self, version1: str, version2: str): # 判断是不是版本号 if (type(version1) != str or type(version2) != str): return -2 if ((not "." in version1) or (not "." in version2)): return -2 if (version1 == version2): return 0 version1List = version1.split(".") version2List = version2.split(".") for i in range(len(version1List)): # 判断 version2List 是否有该长度 try: version2List[i] except: return 1 try: version1 = int(version1List[i]) version2 = int(version2List[i]) except: continue if (version1 > version2): return 1 if (version1 < version2): return -1 if (len(version1List) < len(version2List)): return -1 return 0 def checkTag(self, data: str): result = False no = False if (len(data) > 0 and data[0] == "!"): no = True data = data[1:] if (data == self.arch): result = True if (data == "binfmt" and self.isBinfmt): result = True if (data == "box86" and self.isBox86): result = True if (data == "box64" and self.isBox64): result = True if (data == "lat" and self.isLat): result = True if (data == "lat-i386" and self.isLati386Runtime): result = True if (data == "lat-x86_64" and self.isLatamd64Runtime): result = True if (data == "qemu-user" and self.isQemuUser): result = True if (data == "qemu-user-i386" and self.isQemuUseri386Runtime): result = True if (data == "qemu-user-amd64" and self.isQemuUseramd64Runtime): result = True if (data == "kernel-4k-pagesize" and self.is4kPageSize): result = True if (data == "loong64-kernel-4k-pagesize" and self.isLoongarch and self.is4kPageSize): result = True if (data == "loong64-kernel-8k-pagesize" and self.isLoongarch and self.is8kPageSize): result = True if (data == "loong64-kernel-16k-pagesize" and self.isLoongarch and self.is16kPageSize): result = True if (data == "loong64-kernel-32k-pagesize" and self.isLoongarch and self.is32kPageSize): result = True if (data == "loong64-kernel-64k-pagesize" and self.isLoongarch and self.is64kPageSize): result = True if (data == "proot" and self.isProot): result = True if (data == "android" and self.isAndroid): result = True if (data == "termux" and self.isTermux): result = True if (self.compareVersion(self.glibcVersion, data) == 1): result = True if (os.path.exists(data)): result = True if (no): result = not result return result def checkList(self, data:list): succeed = 0 for i in data: if (type(i) == list): succeed += self.checkList(i) continue if (self.checkTag(i)): succeed += 1 return succeed == len(data) def check(self, data: list): for i in data: if ("all" == i): return True if (type(i) == list): result = self.checkList(i) if (result): return True continue if (self.checkTag(i)): return True return False # 下面内容均翻译自 C++ 版本 def ReadInternetInformation(): global internetJsonList # C++ 版本是用 curl 的,考虑到 Python 用 requests 反而方便,于是不用 curl try: text = requests.get(f"{internetWineSource}/information.json").text print(text) internetJsonList = json.loads(text) except: traceback.print_exc() QtWidgets.QMessageBox.critical(window, "错误", "无法连接服务器!") return nmodel = QtGui.QStandardItemModel(window) newinternetJsonList = [] for i in internetJsonList: if (ui.m_recommendWine.isChecked() and not systemInfo.check(i[2])): continue item = QtGui.QStandardItem(i[0]) nmodel.appendRow(item) newinternetJsonList.append(i) ui.internetWineList.setModel(nmodel) internetJsonList = newinternetJsonList class DownloadThread(QtCore.QThread): MessageBoxInfo = QtCore.pyqtSignal(str) MessageBoxError = QtCore.pyqtSignal(str) ChangeDialog = QtCore.pyqtSignal(QtWidgets.QProgressDialog, int, int, int) Finish = QtCore.pyqtSignal() def __init__(self, progressDialog: QtWidgets.QProgressDialog, url: str, savePath: str, fileName: str, view: QtWidgets.QListView, deleteZip: bool, unzip: bool, localList) -> None: self.dialog = progressDialog self.fileUrl = url self.fileSavePath = savePath self.fileSaveName = fileName self.localView = view self.downloadDeleteZip = deleteZip self.downloadUnzip = unzip self.localJsonList = localList super().__init__() def ReadLocalInformation(self): global localJsonList try: file = open(f"{programPath}/winelist.json", "r"); nmodel = QtGui.QStandardItemModel() localJsonList = json.loads(file.read()) for i in localJsonList: nmodel.appendRow(QtGui.QStandardItem(i)) self.localView.setModel(nmodel) file.close() except: traceback.print_exc() QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc()) def run(self): try: # 创建文件夹 dir = QtCore.QDir() savePath = f"{programPath}/{self.fileSaveName}" # 文件下载 timeout = 0 f = requests.get(self.fileUrl, stream=True) allSize = int(f.headers["content-length"]) # 文件总大小 bytesRead = 0 with open(savePath, "wb") as filePart: for chunk in f.iter_content(chunk_size=1024): if chunk: #progressbar.update(int(part / show)) filePart.write(chunk) bytesRead += 1024 self.ChangeDialog.emit(self.dialog, int(bytesRead / allSize * 100), int(bytesRead / 1024 / 1024), int(allSize / 1024 / 1024)) # 写入配置文件 rfile = open(f"{programPath}/winelist.json", "r") list = json.loads(rfile.read()) rfile.close() # C++ 版注释:不直接用 readwrite 是因为不能覆盖写入 file = open(f"{programPath}/winelist.json", "w") list.append(self.fileSaveName.replace(".7z", "")) file.write(json.dumps(list)) file.close() # 读取配置文件 self.ReadLocalInformation() self.localJsonList = list # 解压文件 shellCommand = "" if self.downloadUnzip: path = f"{programPath}/{self.fileSaveName.replace('.7z', '')}" shellCommand += f"""mkdir -p \"{path}\" 7z x -y \"{savePath}\" -o\"{path}\" """ if self.downloadDeleteZip: shellCommand += f"rm -rf \"{savePath}\"\n" shellFile = open("/tmp/depein-wine-runner-wine-install.sh", "w") shellFile.write(shellCommand) shellFile.close() #process = QtCore.QProcess() #command = ["deepin-terminal", "-e", "bash", "/tmp/depein-wine-runner-wine-install.sh"] #process.start(f"{programPath}/../launch.sh", command) #process.waitForFinished() OpenTerminal("bash /tmp/depein-wine-runner-wine-install.sh") self.Finish.emit() except: traceback.print_exc() self.MessageBoxError.emit(traceback.format_exc()) self.ChangeDialog.emit(self.dialog, 100, 100, 100) self.Finish.emit() def MessageBoxInfo(info): QtWidgets.QMessageBox.information(window, "提示", info) def MessageBoxError(info): QtWidgets.QMessageBox.critical(window, "错误", info) def ChangeDialog(dialog: QtWidgets.QProgressDialog, value, downloadBytes, totalBytes): dialog.setValue(value) dialog.setLabelText(f"{downloadBytes}MB/{totalBytes}MB") def DownloadFinish(): ui.centralWidget.setEnabled(True) class QT: thread = None def on_addButton_clicked(): choose = ui.internetWineList.currentIndex().row() if choose < 0: QtWidgets.QMessageBox.information(window, "提示", "您未选中任何项,无法继续") return downloadName = internetJsonList[choose][1] ReadLocalInformation() for i in localJsonList: if i == internetJsonList[choose][0]: QtWidgets.QMessageBox.information(window, "提示", "您已经安装了这个Wine了!无需重复安装!") return if(ui.deleteZip.isChecked() + ui.unzip.isChecked() == 2): ui.deleteZip.setChecked(False) ui.unzip.setChecked(False) #downloadUrl = internetWineSource + downloadName if "://" in downloadName: downloadUrl = downloadName else: downloadUrl = internetWineSource + downloadName dialog = QtWidgets.QProgressDialog() cancel = QtWidgets.QPushButton("取消") cancel.setDisabled(True) dialog.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg")) dialog.setCancelButton(cancel) dialog.setWindowTitle(f"正在下载“{internetJsonList[choose][0]}”") saveName = os.path.basename(internetJsonList[choose][1]) if os.path.split(os.path.basename(internetJsonList[choose][1]))[0] == "": saveName = os.path.basename(internetJsonList[choose][0]) + ".7z" QT.thread = DownloadThread( dialog, downloadUrl, "", saveName, ui.localWineList, ui.deleteZip.isChecked(), not ui.unzip.isChecked(), localJsonList ) QT.thread.MessageBoxInfo.connect(MessageBoxInfo) QT.thread.MessageBoxError.connect(MessageBoxError) QT.thread.ChangeDialog.connect(ChangeDialog) QT.thread.Finish.connect(DownloadFinish) ui.centralWidget.setDisabled(True) QT.thread.start() def on_delButton_clicked(): if QtWidgets.QMessageBox.question(window, "提示", "你确定要删除吗?") == QtWidgets.QMessageBox.No: return if ui.localWineList.currentIndex().row() < 0: QtWidgets.QMessageBox.information(window, "提示", "您未选择任何项") return try: name = f"{programPath}/{localJsonList[ui.localWineList.currentIndex().row()]}" dir = QtCore.QDir(name) dir.removeRecursively() QtCore.QFile.remove(name + ".7z") del localJsonList[ui.localWineList.currentIndex().row()] file = open(f"{programPath}/winelist.json", "w") file.write(json.dumps(localJsonList)) file.close() ReadLocalInformation() QtWidgets.QMessageBox.information(window, "提示", "删除成功!") except: traceback.print_exc() QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc()) def on_downloadWineFromCloudDisk_clicked(): QtWidgets.QMessageBox.information(window, "提示", "即将在浏览器打开下载页面\n访问密码为 2061") webbrowser.open_new_tab("http://ctfile.gfdgdxi.top/d/31540479-61624693-080e74?p=2061") # 获取当前语言 def get_now_lang()->"获取当前语言": return os.getenv('LANG') if __name__ == "__main__": localJsonList = [] internetJsonList = [] internetWineSourceList = [ "http://wine.wine-runner.gfdgdxi.top/", "http://wine.wine-runner.gfdgdxi.top/sourceforge", "https://gitee.com/gfdgd-xi/wine-mirrors-websize/raw/master/", "https://github.com/gfdgd-xi/wine-mirrors-websize/raw/master/", "http://127.0.0.1/wine-mirrors/" # 本地测试源 ] app = QtWidgets.QApplication(sys.argv) # 读取翻译 if not get_now_lang() == "zh_CN.UTF-8": trans = QtCore.QTranslator() trans.load(f"{programPath}/../LANG/installwine-en_US.qm") app.installTranslator(trans) # 获取信息 systemInfo = GetInfo() # 窗口构建 window = QtWidgets.QMainWindow() ui = Ui_MainWindow() window.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg")) ui.setupUi(window) window.show() # 隐藏选项 ui.unzip.setVisible(False) ui.deleteZip.setVisible(False) # 判断机器所在国家并自动分配源 try: isChina = requests.get("https://ip.useragentinfo.com/json").json()["country"] == "中国" print("IsChina", isChina) if isChina: internetWineSource = internetWineSourceList[0] ui.ipv6Action.setChecked(True) else: internetWineSource = internetWineSourceList[1] ui.kgithubAction.setChecked(True) except: traceback.print_exc() print("IsChina", False) # 请求失败,默认使用国际源 internetWineSource = internetWineSourceList[1] ui.kgithubAction.setChecked(True) # 连接信号 ui.addButton.clicked.connect(on_addButton_clicked) ui.delButton.clicked.connect(on_delButton_clicked) ui.downloadWineFromCloudDisk.clicked.connect(on_downloadWineFromCloudDisk_clicked) ui.addOtherWine.clicked.connect(InstallOtherWine) ui.changeSourcesGroup.triggered.connect(ChangeSources) ui.m_recommendWine.clicked.connect(ReadInternetInformation) ## 加载内容 # 设置列表双击不会编辑 ui.localWineList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) ui.internetWineList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) # 读取信息 ReadLocalInformation() ReadInternetInformation() # 图标 ui.centralWidget.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg")) app.exec_()