diff --git a/main-newguipyqt.py b/main-newguipyqt.py
new file mode 100755
index 0000000..5dc7aec
--- /dev/null
+++ b/main-newguipyqt.py
@@ -0,0 +1,1639 @@
+#!/usr/bin/env python3
+# 使用系统默认的 python3 运行
+###########################################################################################
+# 作者:gfdgd xi、为什么您不喜欢熊出没和阿布呢
+# 版本:1.7.0
+# 更新时间:2022年07月16日
+# 感谢:感谢 wine 以及 deepin-wine 团队,提供了 wine 和 deepin-wine 给大家使用,让我能做这个程序
+# 基于 Python3 的 tkinter 构建
+###########################################################################################
+#################
+# 引入所需的库
+#################
+import os
+import sys
+import time
+import json
+import shutil
+import easygui
+import requests
+import threading
+import traceback
+import ttkthemes
+import webbrowser
+import subprocess
+import ttkbootstrap
+import tkinter as tk
+import tkinter.ttk as ttk
+import tkinter.filedialog
+import tkinter.messagebox
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import PyQt5.QtWidgets as QtWidgets
+import PIL.Image as Image
+import PIL.ImageTk as ImageTk
+
+###################
+# 程序所需事件
+###################
+
+# 打开程序官网
+def OpenProgramURL():
+ webbrowser.open_new_tab(programUrl)
+
+# 读取文本文档
+def readtxt(path):
+ f = open(path, "r") # 设置文件对象
+ str = f.read() # 获取内容
+ f.close() # 关闭文本对象
+ return str # 返回结果
+
+# 写入文本文档
+def write_txt(path, things):
+ file = open(path, 'w', encoding='UTF-8') # 设置文件对象
+ file.write(things) # 写入文本
+ file.close() # 关闭文本对象
+
+# 获取用户桌面目录
+def get_desktop_path():
+ for line in open(get_home() + "/.config/user-dirs.dirs"): # 以行来读取配置文件
+ desktop_index = line.find("XDG_DESKTOP_DIR=\"") # 寻找是否有对应项,有返回 0,没有返回 -1
+ if desktop_index != -1: # 如果有对应项
+ break # 结束循环
+ if desktop_index == -1: # 如果是提前结束,值一定≠-1,如果是没有提前结束,值一定=-1
+ return -1
+ else:
+ get = line[17:-2] # 截取桌面目录路径
+ get_index = get.find("$HOME") # 寻找是否有对应的项,需要替换内容
+ if get != -1: # 如果有
+ get = get.replace("$HOME", get_home()) # 则把其替换为用户目录(~)
+ return get # 返回目录
+
+# 获取用户主目录
+def get_home():
+ return os.path.expanduser('~')
+
+# 第一个浏览按钮事件
+def liulanbutton():
+ path = QtWidgets.QFileDialog.getExistingDirectory(widget, "选择 wine 容器", json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBotton.json"))["path"])
+ if path != "" and path != "()":
+ e1.setEditText(path)
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineBotton.json", json.dumps({"path": path})) # 写入配置文件
+
+# 第二个浏览按钮事件
+def liulanexebutton():
+ path = QtWidgets.QFileDialog.getOpenFileName(widget, "选择 exe 可执行文件", json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExe.json"))["path"], "exe 可执行文件(*.exe);;EXE 可执行文件(*.EXE);;所有文件(*.*)")
+ #path = tkinter.filedialog.askopenfilename(title="选择 exe 可执行文件", filetypes=[("exe 可执行文件", "*.exe"), ("EXE 可执行文件", "*.EXE"), ("所有文件", "*.*")], initialdir=json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExe.json"))["path"])
+ if path != "" and path != "()":
+ e2.setEditText(path[0]) # 显示路径
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindExe.json", json.dumps({"path": os.path.dirname(path[0])})) # 写入配置文件
+
+run = None
+# 使用多线程运行可执行文件
+def runexebutton(self):
+ global run
+ DisableButton(True)
+ if not CheckProgramIsInstall(wine[o1.currentText()]):
+ #if not tkinter.messagebox.askyesno(title="提示", message="检查到您未安装这个 wine,是否继续使用这个 wine 运行?"):
+ if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 运行?") == QtWidgets.QMessageBox.No:
+ DisableButton(False)
+ return
+ if e2.currentText() == "": # 判断文本框是否有内容
+ QtWidgets.QMessageBox.information(widget, "提示", "没有填写需要使用的 exe 应用")
+ DisableButton(False)
+ return
+ returnText.setText("")
+ run = Runexebutton_threading()
+ run.signal.connect(QT.ShowWineReturn)
+ run.showHistory.connect(QT.ShowHistory)
+ run.start()
+
+class QT:
+ message = None
+ def ShowWineReturn(things):
+ returnText.insertPlainText(things)
+
+ def ShowHistory(temp):
+ e1.clear()
+ e2.clear()
+ e2.addItems(wineBottonHistory)
+ e2.setEditText(wineBottonHistory[-1])
+ e1.addItems(findExeHistory)
+ e1.setEditText(findExeHistory[-1])
+
+def DisableButton(things):
+ button1.setDisabled(things)
+ button2.setDisabled(things)
+ button3.setDisabled(things)
+ wineConfig.setDisabled(things)
+ e1.setDisabled(things)
+ e2.setDisabled(things)
+ o1.setDisabled(things)
+ #winetricksOpen.configure(state=a[things])
+ getProgramIcon.setDisabled(things)
+ uninstallProgram.setDisabled(things)
+ trasButton.setDisabled(things)
+
+def CheckProgramIsInstall(program):
+ return not bool(os.system(f"which '{program}'"))
+class Runexebutton_threading(QtCore.QThread):
+ signal = QtCore.pyqtSignal(str)
+ showHistory = QtCore.pyqtSignal(str)
+ def __init__(self):
+ super().__init__()
+
+ def run(self):
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ option = ""
+ if setting["Architecture"] != "Auto":
+ option += f"WINEARCH={setting['Architecture']} "
+ if not setting["Debug"]:
+ option += "WINEDEBUG=-all "
+ if setting["TerminalOpen"]:
+ res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"] + "\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ else:
+ res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ # 实时读取程序返回
+ #
+ while res.poll() is None:
+ try:
+ text = res.stdout.readline().decode("utf8")
+ except:
+ text = ""
+ self.signal.emit(text)
+ print(text)
+ findExeHistory.append(wineBottonPath) # 将记录写进数组
+ wineBottonHistory.append(e2.currentText()) # 将记录写进数组
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", str(json.dumps(ListToDictionary(findExeHistory)))) # 将历史记录的数组转换为字典并写入
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", str(json.dumps(ListToDictionary(wineBottonHistory)))) # 将历史记录的数组转换为字典并写入
+ self.showHistory.emit("")
+ DisableButton(False)
+
+
+# 显示“关于这个程序”窗口
+def about_this_program()->"显示“关于这个程序”窗口":
+ global about
+ global title
+ global iconPath
+ QT.message = QtWidgets.QMainWindow()
+ messageWidget = QtWidgets.QWidget()
+ QT.message.setWindowTitle(f"关于 {title}")
+ messageLayout = QtWidgets.QGridLayout()
+ messageLayout.addWidget(QtWidgets.QLabel(f""), 0, 0, 1, 1, QtCore.Qt.AlignTop)
+ aboutInfo = QtWidgets.QTextBrowser(messageWidget)
+ aboutInfo.setHtml(about)
+ messageLayout.addWidget(aboutInfo, 0, 1, 1, 1)
+ ok = QtWidgets.QPushButton("确定")
+ ok.clicked.connect(QT.message.close)
+ messageLayout.addWidget(ok, 1, 1, 1, 1, QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight)
+ messageWidget.setLayout(messageLayout)
+ QT.message.setCentralWidget(messageWidget)
+ QT.message.resize(messageWidget.frameGeometry().width() * 1.5, messageWidget.frameGeometry().height() * 1.5)
+ QT.message.show()
+
+# 显示“提示”窗口
+def helps():
+ global tips
+ QtWidgets.QMessageBox.information(widget, "提示", tips)
+
+# 显示更新内容窗口
+def UpdateThings():
+ QtWidgets.QMessageBox.information(widget, "更新内容", updateThings)
+
+# 生成 desktop 文件在启动器
+def make_desktop_on_launcher():
+ if combobox1.currentText() == "" or e2.currentText() == "": # 判断文本框是否有内容
+ QtWidgets.QMessageBox.information(widget, "提示", "没有填写需要使用 exe 应用或保存的文件名")
+ return
+ if not CheckProgramIsInstall(wine[o1.currentText()]):
+ if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 写入?") == QtWidgets.QMessageBox.No:
+ DisableButton(False)
+ return
+ else: # 如果都有
+ if os.path.exists(get_home() + "/.local/share/applications/" + combobox1.currentText() + ".desktop"): # 判断目录是否有该文件,如果有
+ choose = QtWidgets.QMessageBox.question(widget, "提示", "文件已经存在,是否覆盖?") == QtWidgets.QMessageBox.Yes
+ if choose: # 如要覆盖
+ os.remove(get_home() + "/.local/share/applications/" + combobox1.currentText() + ".desktop") # 删除该文件
+ else: # 如不覆盖
+ return # 结束
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ option = ""
+ if setting["Architecture"] != "Auto":
+ option += f"WINEARCH={setting['Architecture']} "
+ if not setting["Debug"]:
+ option += "WINEDEBUG=-all "
+ write_txt(get_home() + "/.local/share/applications/" + combobox1.currentText() + ".desktop", f'''[Desktop Entry]
+Name={combobox1.currentText()}
+Exec=env WINEPREFIX='{wineBottonPath}' {option} {wine[o1.currentText()]} '{e2.currentText()}' {setting["WineOption"]}
+Icon={iconPath}
+Type=Application
+StartupNotify=true''') # 写入文本文档
+ shellHistory.append(combobox1.currentText()) # 将记录写进数组
+ write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", str(json.dumps(ListToDictionary(shellHistory)))) # 将历史记录的数组转换为字典并写入
+ combobox1.clear()
+ combobox1.addItems(shellHistory)
+ QtWidgets.QMessageBox.information(widget, "提示", "生成完成!") # 显示完成对话框
+
+# 生成 desktop 文件在桌面
+# (第四个按钮的事件)
+def make_desktop_on_desktop():
+ if combobox1.currentText() == "" or e2.currentText() == "": # 判断文本框是否有内容
+ QtWidgets.QMessageBox.information(widget, "提示", "没有填写需要使用 exe 应用或保存的文件名")
+ return
+ if not CheckProgramIsInstall(wine[o1.currentText()]):
+ if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 写入?") == QtWidgets.QMessageBox.No:
+ DisableButton(False)
+ return
+ else: # 如果都有
+ if os.path.exists(get_desktop_path() + "/" + combobox1.currentText() + ".desktop"): # 判断目录是否有该文件,如果有
+ choose = QtWidgets.QMessageBox.question(widget, "提示", "文件已经存在,是否覆盖?") == QtWidgets.QMessageBox.Yes
+ if choose: # 如要覆盖
+ os.remove(get_desktop_path() + "/" + combobox1.currentText() + ".desktop") # 删除该文件
+ else: # 如不覆盖
+ return # 结束
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.mknod(get_desktop_path() + "/" + combobox1.currentText() + ".desktop")
+ option = ""
+ if setting["Architecture"] != "Auto":
+ option += f"WINEARCH={setting['Architecture']} "
+ if not setting["Debug"]:
+ option += "WINEDEBUG=-all "
+ write_txt(get_desktop_path() + "/" + combobox1.currentText() + ".desktop", f'''[Desktop Entry]
+Name={combobox1.currentText()}
+Exec=env WINEPREFIX='{wineBottonPath}' {option} {wine[o1.currentText()]} '{e2.currentText()}' {setting["WineOption"]}
+Icon={iconPath}
+Type=Application
+StartupNotify=true''') # 写入文本文档
+ shellHistory.append(combobox1.currentText()) # 将记录写进数组
+ write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", str(json.dumps(ListToDictionary(shellHistory)))) # 将历史记录的数组转换为字典并写入
+ combobox1.clear()
+ combobox1.addItems(shellHistory)
+ QtWidgets.QMessageBox.information(widget, "提示", "生成完成!") # 显示完成对话框
+
+# 数组转字典
+def ListToDictionary(list):
+ dictionary = {}
+ for i in range(len(list)):
+ dictionary[i] = list[i]
+ return dictionary
+
+def CleanProgramHistory():
+ if tkinter.messagebox.askokcancel(title="警告", message="删除后将无法恢复,你确定吗?\n删除后软件将会自动重启。"):
+ shutil.rmtree(get_home() + "/.config/deepin-wine-runner")
+ ReStartProgram()
+
+# 重启本应用程序
+def ReStartProgram():
+ python = sys.executable
+ os.execl(python, python, * sys.argv)
+
+def KillProgram():
+ os.system(f"killall {wine[o1.currentText()]} -9")
+ os.system("killall winedbg -9")
+
+def InstallWine():
+ threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -e \"{programPath}/AllInstall.py\""]).start()
+
+def OpenWineBotton():
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.system("xdg-open \"" + wineBottonPath.replace("\'", "\\\'") + "\"")
+
+def OpenWineFontPath():
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ QtWidgets.QMessageBox.information(widget, "提示", "如果安装字体?只需要把字体文件复制到此字体目录\n按下“OK”按钮可以打开字体目录")
+ os.system("xdg-open \"" + wineBottonPath.replace("\'", "\\\'") + "/drive_c/windows/Fonts\"")
+
+class RunWineProgramThread(QtCore.QThread):
+ signal = QtCore.pyqtSignal(str)
+ showHistory = QtCore.pyqtSignal(str)
+ def __init__(self, wineProgram, history = False, Disbled = True):
+ super().__init__()
+ self.wineProgram = wineProgram
+ self.history = history
+ self.Disbled = Disbled
+
+ def run(self):
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ option = ""
+ if setting["Architecture"] != "Auto":
+ option += f"WINEARCH={setting['Architecture']} "
+ if not setting["Debug"]:
+ option += "WINEDEBUG=-all "
+ if setting["TerminalOpen"]:
+ res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"] + "\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ else:
+ res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ # 实时读取程序返回
+ while res.poll() is None:
+ try:
+ text = res.stdout.readline().decode("utf8")
+ except:
+ text = ""
+ self.signal.emit(text)
+ print(text)
+ if self.history:
+ findExeHistory.append(wineBottonPath) # 将记录写进数组
+ wineBottonHistory.append(e2.currentText()) # 将记录写进数组
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", str(json.dumps(ListToDictionary(findExeHistory)))) # 将历史记录的数组转换为字典并写入
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", str(json.dumps(ListToDictionary(wineBottonHistory)))) # 将历史记录的数组转换为字典并写入
+ self.showHistory.emit("")
+ #e1['value'] = findExeHistory
+ #e2['value'] = wineBottonHistory
+ if self.Disbled:
+ DisableButton(False)
+
+
+runProgram = None
+def RunWineProgram(wineProgram, history = False, Disbled = True):
+ global runProgram
+ DisableButton(True)
+ if not CheckProgramIsInstall(wine[o1.currentText()]):
+ if not tkinter.messagebox.askyesno(title="提示", message="检查到您未安装这个 wine,是否继续使用这个 wine 运行?"):
+ DisableButton(False)
+ return
+ returnText.setText("")
+ runProgram = RunWineProgramThread(wineProgram, history, Disbled)
+ runProgram.signal.connect(QT.ShowWineReturn)
+ runProgram.showHistory.connect(QT.ShowHistory)
+ runProgram.start()
+
+class RunWinetricksThread(QtCore.QThread):
+ signal = QtCore.pyqtSignal(str)
+ def __init__(self):
+ super().__init__()
+
+ def run(self):
+ wineBottonPath = setting["DefultBotton"]
+ if not e1.currentText() == "":
+ wineBottonPath = e1.currentText()
+ option = ""
+ if setting["Architecture"] != "Auto":
+ option += f"WINEARCH={setting['Architecture']} "
+ if not setting["Debug"]:
+ option += "WINEDEBUG=-all "
+ if setting["TerminalOpen"]:
+ res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='{wineBottonPath}' {option} WINE=" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + " winetricks --gui\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ else:
+ res = subprocess.Popen([f"WINEPREFIX='{wineBottonPath}' {option} WINE='" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + "' winetricks --gui"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ # 实时读取程序返回
+ while res.poll() is None:
+ try:
+ text = res.stdout.readline().decode("utf8")
+ except:
+ text = ""
+ self.signal.emit(text)
+ print(text, end="")
+ DisableButton(False)
+
+runWinetricks = None
+def RunWinetricks():
+ global runWinetricks
+ DisableButton(True)
+ if not CheckProgramIsInstall(wine[o1.currentText()]):
+ if not tkinter.messagebox.askyesno(title="提示", message="检查到您未安装这个 wine,是否继续使用这个 wine 运行?"):
+ DisableButton(False)
+ return
+ returnText.setText("")
+ runWinetricks = RunWinetricksThread()
+ runWinetricks.signal.connect(QT.ShowWineReturn)
+ runWinetricks.start()
+
+
+
+def InstallMonoGecko(program):
+ DisableButton(True)
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"'{programPath}/InstallMono.py' '{wineBottonPath}' {wine[o1.currentText()]} {program}\" --keep-open")
+ DisableButton(False)
+
+def InstallNetFramework():
+ DisableButton(True)
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"'{programPath}/InstallNetFramework.py' '{wineBottonPath}' {wine[o1.currentText()]}\" --keep-open")
+ DisableButton(False)
+
+def InstallVisualStudioCPlusPlus():
+ DisableButton(True)
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"'{programPath}/InstallVisualCPlusPlus.py' '{wineBottonPath}' {wine[o1.currentText()]}\" --keep-open")
+ DisableButton(False)
+
+def InstallMSXML():
+ DisableButton(True)
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"'{programPath}/InstallMsxml.py' '{wineBottonPath}' {wine[o1.currentText()]}\" --keep-open")
+ DisableButton(False)
+
+def InstallOther():
+ DisableButton(True)
+ if e1.currentText()== "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"'{programPath}/InstallOther.py' '{wineBottonPath}' {wine[o1.currentText()]}\" --keep-open")
+ DisableButton(False)
+
+def BuildExeDeb():
+ if e1.get() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ threading.Thread(target=os.system, args=[f"python3 '{programPath}/deepin-wine-packager.py' '{wineBottonPath}' '{wine[o1.currentText()]}'"]).start()
+
+def SetDeepinFileDialogDeepin():
+ code = os.system(f"pkexec \"{programPath}/deepin-wine-venturi-setter.py\" deepin")
+ if code != 0:
+ if code == 1:
+ QtWidgets.QMessageBox.critical(widget, "错误", "无法更新配置:配置不准重复配置")
+ return
+ QtWidgets.QMessageBox.critical(widget, "错误", "配置失败")
+ return
+ QtWidgets.QMessageBox.information(widget, "提示", "设置完成!")
+
+def SetDeepinFileDialogDefult():
+ code = os.system(f"pkexec \"{programPath}/deepin-wine-venturi-setter.py\" defult")
+ if code != 0:
+ if code == 1:
+ QtWidgets.QMessageBox.critical(widget, "错误", "无法更新配置:配置不准重复配置")
+ return
+ QtWidgets.QMessageBox.critical(widget, "错误", "配置失败")
+ return
+ QtWidgets.QMessageBox.information(widget, "提示", "设置完成!")
+
+def SetDeepinFileDialogRecovery():
+ threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec \"{programPath}/deepin-wine-venturi-setter.py\" recovery' --keep-open"]).start()
+
+def DeleteWineBotton():
+ if QtWidgets.QMessageBox.question(widget, "提示", "你确定要删除容器吗?删除后将无法恢复!\n如果没有选择 wine 容器,将会自动删除默认的容器!") == QtWidgets.QMessageBox.No:
+ return
+ if e1.currentText() == "":
+ wineBottonPath = setting["DefultBotton"]
+ else:
+ wineBottonPath = e1.currentText()
+ try:
+ shutil.rmtree(wineBottonPath)
+ QtWidgets.QMessageBox.information(widget, "提示", "删除完毕!")
+ except:
+ traceback.print_exc()
+ QtWidgets.QMessageBox.critical(widget, "错误", traceback.format_exc())
+
+def ThankWindow():
+ # 直接显示关于窗口,关于窗口已经添加
+ about_this_program()
+
+def InstallWineFont():
+ threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'echo 这些字体来自星火应用商店 && sudo ss-apt-fast install ms-core-fonts winfonts -y' --keep-open"]).start()
+
+def WineRunnerBugUpload():
+ threading.Thread(target=os.system, args=[f"'{programPath}/deepin-wine-runner-update-bug'"]).start()
+
+def GetScreenSize():
+ screenInformation = []
+ # 使用 xrandr 进行筛选
+ for i in subprocess.getoutput("xrandr").split('\n'):
+ if not " connected " in i: # 检测连接的显示器
+ continue
+ # 获取分辨率基本信息,如
+ # DisplayPort-0 connected 1600x900+1280+0 (normal left inverted right x axis y axis) 434mm x 236mm
+ # 先判断是否为主屏幕
+ main = False
+ if "primary" in i:
+ main = True
+ # 进行进一步筛选
+ i = i[i.index("connected"):].replace("connected", "").replace("primary", "")
+ # 进行初步筛选,如
+ # 1600x900+1280+0 (normal left inverted right x axis y axis) 434mm x 236mm
+ i = i[:i.index("(")].replace(" ", "")
+ # 筛选为 1600x900+0+0 进行最后数值的提取
+ screenInformation.append([
+ int(i[:i.index("x")]), # 获取宽度
+ int(i[i.index("x") + 1 :i.index("+")]), # 获取高度
+ int(i[i.index("+") + 1:].split('+')[0]), # 获取显示屏 X 坐标
+ int(i[i.index("+") + 1:].split('+')[1]), # 获取显示屏 Y 坐标
+ main # 是否为主屏幕
+ ])
+ return screenInformation # 返回结果
+
+def UOSPackageScript():
+ threading.Thread(target=os.system, args=[f"python3 '{programPath}/deepin-wine-packager-with-script.py'"]).start()
+
+def RunVM():
+ threading.Thread(target=os.system, args=[f"bash '{programPath}/RunVM.sh'"]).start()
+
+class UpdateWindow():
+ data = {}
+ update = None
+ def ShowWindow():
+ UpdateWindow.update = QtWidgets.QMainWindow()
+ updateWidget = QtWidgets.QWidget()
+ updateWidgetLayout = QtWidgets.QGridLayout()
+ versionLabel = QtWidgets.QLabel(f"当前版本:{version}\n最新版本:未知\n更新内容:")
+ updateText = QtWidgets.QTextBrowser()
+ ok = QtWidgets.QPushButton("更新(更新过程中会关闭所有Python应用,包括这个应用)")
+ ok.clicked.connect(UpdateWindow.Update)
+ cancel = QtWidgets.QPushButton("取消")
+ cancel.clicked.connect(UpdateWindow.update.close)
+ try:
+ UpdateWindow.data = json.loads(requests.get("http://120.25.153.144/spark-deepin-wine-runner/update.json").text)
+ versionLabel = QtWidgets.QLabel(f"当前版本:{version}\n最新版本:{UpdateWindow.data['Version']}\n更新内容:")
+ if UpdateWindow.data["Version"] == version:
+ updateText.setText("此为最新版本,无需更新")
+ ok.setDisabled(True)
+ else:
+ updateText.setText(UpdateWindow.data["New"].replace("\\n", "\n"))
+ except:
+ traceback.print_exc()
+ QtWidgets.QMessageBox.critical(updateWidget, "错误", "无法连接服务器!")
+ updateWidgetLayout.addWidget(versionLabel, 0, 0, 1, 1)
+ updateWidgetLayout.addWidget(updateText, 1, 0, 1, 3)
+ updateWidgetLayout.addWidget(ok, 2, 2, 1, 1)
+ updateWidgetLayout.addWidget(cancel, 2, 1, 1, 1)
+ updateWidget.setLayout(updateWidgetLayout)
+ UpdateWindow.update.setCentralWidget(updateWidget)
+ UpdateWindow.update.setWindowTitle("检查更新")
+ UpdateWindow.update.resize(updateWidget.frameGeometry().width(), updateWidget.frameGeometry().height() * 1.5)
+ UpdateWindow.update.show()
+ return
+ update = tk.Toplevel()
+ update.title("检查更新")
+ update.resizable(0, 0)
+ update.iconphoto(False, tk.PhotoImage(file=iconPath))
+ versionLabel = ttk.Label(update, text="当前版本:{}\n最新版本:未知\n更新内容:".format(version))
+ updateText = tk.Text(update)
+ controlFrame = ttk.Frame(update)
+ ok = ttk.Button(controlFrame, text="更新(更新过程中会关闭所有Python应用,包括这个应用)", command=UpdateWindow.Update)
+ cancel = ttk.Button(controlFrame, text="取消", command=update.quit)
+ try:
+ UpdateWindow.data = json.loads(requests.get("http://120.25.153.144/spark-deepin-wine-runner/update.json").text)
+ versionLabel = ttk.Label(update, text="当前版本:{}\n最新版本:{}\n更新内容:".format(version, UpdateWindow.data["Version"]))
+ if UpdateWindow.data["Version"] == version:
+ updateText.insert("0.0", "此为最新版本,无需更新")
+ ok.configure(state=tk.DISABLED)
+ else:
+ updateText.insert("0.0", UpdateWindow.data["New"].replace("\\n", "\n"))
+ except:
+ traceback.print_exc()
+ tkinter.messagebox.showerror(title="错误", message="无法连接服务器!")
+ updateText.configure(state=tk.DISABLED)
+ versionLabel.pack(anchor=tk.W)
+ updateText.pack()
+ controlFrame.pack(anchor=tk.E)
+ cancel.grid(row=0, column=0)
+ ok.grid(row=0, column=1)
+ update.mainloop()
+ def Update():
+ if os.path.exists("/tmp/spark-deepin-wine-runner/update"):
+ shutil.rmtree("/tmp/spark-deepin-wine-runner/update")
+ os.makedirs("/tmp/spark-deepin-wine-runner/update")
+ try:
+ print(UpdateWindow.data["Url"])
+ write_txt("/tmp/spark-deepin-wine-runner/update.sh", f"""#!/bin/bash
+echo 删除多余的安装包
+rm -rfv /tmp/spark-deepin-wine-runner/update/*
+echo 关闭“Wine 运行器”以及其它“Python 应用”
+killall python3
+echo 下载安装包
+wget -P /tmp/spark-deepin-wine-runner/update {UpdateWindow.data["Url"][0]}
+echo 安装安装包
+dpkg -i /tmp/spark-deepin-wine-runner/update/*
+echo 修复依赖关系
+apt install -f -y
+notify-send -i "{iconPath}" "更新完毕!"
+zenity --info --text=\"更新完毕!\" --ellipsize
+""")
+ except:
+ traceback.print_exc()
+ QtWidgets.QMessageBox.critical(None, "出现错误,无法继续更新", traceback.format_exc())
+ os.system(f"'{programPath}/launch.sh' deepin-terminal -e pkexec bash /tmp/spark-deepin-wine-runner/update.sh")
+
+class GetDllFromWindowsISO:
+ wineBottonPath = get_home() + "/.wine"
+ isoPath = None#ttk.Entry()
+ dllList = None
+ message = None
+ dllFound = None
+ dllControl = None
+ foundButton = None
+ saveDll = None
+ setWineBotton = None
+ browser = None
+ mount = False
+ mountButton = None
+ def ShowWindow():
+ DisableButton(True)
+ GetDllFromWindowsISO.message = tk.Toplevel()
+ if not e1.currentText() == "":
+ GetDllFromWindowsISO.wineBottonPath = e1.currentText()
+ ttk.Label(GetDllFromWindowsISO.message, text=f"""提示:
+ 目前本提取功能只支持 Windows XP 以及 Windows Server 2003 等老系统的官方安装镜像,只支持读取 i386 安装方法的安装镜像,不支持读取 wim、ghost 安装方式
+ 以及不要拷贝/替换太多的 dll,否则可能会导致 wine 容器异常
+ 最后,拷贝/替换 dll 后,建议点击下面“设置 wine 容器”按钮==》函数库 进行设置
+当前选择的 Wine 容器:{GetDllFromWindowsISO.wineBottonPath}""").grid(row=0, column=0, columnspan=3, sticky=tk.W)
+ ttk.Label(GetDllFromWindowsISO.message, text="ISO镜像:").grid(row=1, column=0, sticky=tk.W)
+ GetDllFromWindowsISO.isoPath = ttk.Combobox(GetDllFromWindowsISO.message, width=100)
+ GetDllFromWindowsISO.browser = ttk.Button(GetDllFromWindowsISO.message, text="浏览……", command=GetDllFromWindowsISO.Browser)
+ isoControl = ttk.Frame(GetDllFromWindowsISO.message)
+ GetDllFromWindowsISO.mountButton = ttk.Button(isoControl, text="读取/挂载ISO镜像", command=GetDllFromWindowsISO.MountDisk)
+ ttk.Button(isoControl, text="关闭/卸载ISO镜像", command=GetDllFromWindowsISO.UmountDisk).grid(row=0, column=1)
+ ttk.Label(GetDllFromWindowsISO.message, text="查找DLL\n(为空则代表不查找,\n将显示全部内容):").grid(row=3, column=0)
+ GetDllFromWindowsISO.dllFound = ttk.Combobox(GetDllFromWindowsISO.message, width=100)
+ GetDllFromWindowsISO.foundButton = ttk.Button(GetDllFromWindowsISO.message, text="查找", command=GetDllFromWindowsISO.Found)
+ GetDllFromWindowsISO.dllList = tk.Listbox(GetDllFromWindowsISO.message, width=100)
+ GetDllFromWindowsISO.dllControl = ttk.Frame(GetDllFromWindowsISO.message)
+ GetDllFromWindowsISO.saveDll = ttk.Button(GetDllFromWindowsISO.dllControl, text="保存到 wine 容器中", command=GetDllFromWindowsISO.CopyDll)
+ GetDllFromWindowsISO.setWineBotton = ttk.Button(GetDllFromWindowsISO.dllControl, text="设置 wine 容器", command=lambda: threading.Thread(target=RunWineProgram, args=["winecfg", False, False]).start())
+ # 设置控件
+ GetDllFromWindowsISO.DisbledDown(True)
+ GetDllFromWindowsISO.isoPath['value'] = isoPath
+ GetDllFromWindowsISO.dllFound['value'] = isoPathFound
+ # 显示控件
+ GetDllFromWindowsISO.isoPath.grid(row=1, column=1)
+ GetDllFromWindowsISO.browser.grid(row=1, column=2)
+ GetDllFromWindowsISO.mountButton.grid(row=0, column=0)
+ isoControl.grid(row=2, column=0, columnspan=3)
+ GetDllFromWindowsISO.dllFound.grid(row=3, column=1)
+ GetDllFromWindowsISO.foundButton.grid(row=3, column=2)
+ GetDllFromWindowsISO.dllList.grid(row=4, column=0, columnspan=3)
+ GetDllFromWindowsISO.dllControl.grid(row=5, column=0, columnspan=3)
+ GetDllFromWindowsISO.saveDll.grid(row=0, column=0)
+ GetDllFromWindowsISO.setWineBotton.grid(row=0, column=1)
+ # 设置
+ GetDllFromWindowsISO.message.protocol('WM_DELETE_WINDOW', GetDllFromWindowsISO.ExitWindow)
+ GetDllFromWindowsISO.message.title(f"Wine 运行器 {version}——从 ISO 提取 DLL")
+ # 显示
+ GetDllFromWindowsISO.message.mainloop()
+
+ def DisbledUp(state):
+ nd = [tk.NORMAL, tk.DISABLED]
+ GetDllFromWindowsISO.isoPath.configure(state=nd[int(state)])
+ GetDllFromWindowsISO.browser.configure(state=nd[int(state)])
+ GetDllFromWindowsISO.mountButton.configure(state=nd[int(state)])
+
+
+ def DisbledDown(state):
+ nd = [tk.NORMAL, tk.DISABLED]
+ GetDllFromWindowsISO.dllList.configure(state=nd[int(state)])
+ GetDllFromWindowsISO.dllFound.configure(state=nd[int(state)])
+ #GetDllFromWindowsISO.dllControl.configure(state=nd[int(state)])
+ GetDllFromWindowsISO.saveDll.configure(state=nd[int(state)])
+ GetDllFromWindowsISO.setWineBotton.configure(state=nd[int(state)])
+ GetDllFromWindowsISO.foundButton.configure(state=nd[int(state)])
+
+ def Browser():
+ path = tkinter.filedialog.askopenfilename(title="选择 ISO 镜像文件",
+ filetypes=[("ISO 镜像文件", "*.iso"), ("ISO 镜像文件", "*.ISO"), ("所有文件", "*.*")],
+ initialdir=json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindISO.json"))["path"])
+ if path == None or path == "":
+ return
+ GetDllFromWindowsISO.isoPath.set(path)
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindISO.json", json.dumps({"path": os.path.dirname(path)})) # 写入配置文件
+
+ def Found():
+ found = GetDllFromWindowsISO.dllFound.get()
+ GetDllFromWindowsISO.dllList.configure(state=tk.NORMAL)
+ GetDllFromWindowsISO.dllList.delete(0, tk.END)
+ try:
+ if found == "":
+ for i in os.listdir("/tmp/wine-runner-getdll/i386"):
+ if i[-3:] == "dl_":
+ GetDllFromWindowsISO.dllList.insert("end", i[:-1] + "l")
+ return
+ for i in os.listdir("/tmp/wine-runner-getdll/i386"):
+ if found in i[:-1] + "l":
+ GetDllFromWindowsISO.dllList.insert("end", i[:-1] + "l")
+ isoPathFound.append(found) # 将记录写进数组
+ write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", str(json.dumps(ListToDictionary(isoPathFound)))) # 将历史记录的数组转换为字典并写入
+ GetDllFromWindowsISO.dllFound['value'] = isoPathFound
+ except:
+ traceback.print_exc()
+ tkinter.messagebox.showerror(title="错误", message=traceback.format_exc())
+
+
+ def ExitWindow():
+ if GetDllFromWindowsISO.mount:
+ tkinter.messagebox.showinfo(title="提示", message="请关闭/卸载镜像后再关闭本窗口")
+ return
+ DisableButton(False)
+ GetDllFromWindowsISO.message.quit()
+
+ def MountDisk():
+ if not os.path.exists(GetDllFromWindowsISO.isoPath.get()):
+ tkinter.messagebox.showerror(title="错误", message="您选择的 ISO 镜像文件不存在")
+ return
+ if os.path.exists("/tmp/wine-runner-getdll"):
+ try:
+ os.rmdir("/tmp/wine-runner-getdll")
+ except:
+ # 如果无法删除可能是挂载了文件
+ os.system("pkexec umount /tmp/wine-runner-getdll")
+ try:
+ os.rmdir("/tmp/wine-runner-getdll")
+ except:
+ traceback.print_exc()
+ tkinter.messagebox.showerror(title="错误", message=traceback.format_exc())
+ return
+ os.makedirs("/tmp/wine-runner-getdll")
+ GetDllFromWindowsISO.dllList.configure(state=tk.NORMAL)
+ os.system(f"pkexec mount '{GetDllFromWindowsISO.isoPath.get()}' /tmp/wine-runner-getdll")
+ GetDllFromWindowsISO.dllList.delete(0, tk.END)
+ try:
+ for i in os.listdir("/tmp/wine-runner-getdll/i386"):
+ if i[-3:] == "dl_":
+ GetDllFromWindowsISO.dllList.insert("end", i[:-1] + "l")
+ except:
+ traceback.print_exc()
+ tkinter.messagebox.showerror(title="错误", message=f"镜像内容读取/挂载失败,报错如下:\n{traceback.format_exc()}")
+ return
+ GetDllFromWindowsISO.DisbledDown(False)
+ GetDllFromWindowsISO.DisbledUp(True)
+ GetDllFromWindowsISO.mount = True
+ isoPath.append(GetDllFromWindowsISO.isoPath.get()) # 将记录写进数组
+ write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", str(json.dumps(ListToDictionary(isoPath)))) # 将历史记录的数组转换为字典并写入
+ GetDllFromWindowsISO.isoPath['value'] = isoPath
+
+ def UmountDisk():
+ os.system("pkexec umount /tmp/wine-runner-getdll")
+ GetDllFromWindowsISO.dllList.configure(state=tk.NORMAL)
+ try:
+ shutil.rmtree("/tmp/wine-runner-getdll")
+ except:
+ traceback.print_exc()
+ tkinter.messagebox.showerror(title="错误", message=f"关闭/卸载镜像失败,报错如下:\n{traceback.format_exc()}")
+ return
+ GetDllFromWindowsISO.DisbledDown(True)
+ GetDllFromWindowsISO.DisbledUp(False)
+ GetDllFromWindowsISO.mount = False
+
+ def CopyDll():
+ for i in GetDllFromWindowsISO.dllList.curselection():
+ choose = GetDllFromWindowsISO.dllList.get(i)
+ if os.path.exists(f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}"):
+ if not tkinter.messagebox.askyesno(title="提示", message=f"DLL {choose} 已经存在,是否覆盖?"):
+ continue
+ print(i)
+ try:
+ shutil.copy(f"/tmp/wine-runner-getdll/i386/{choose[:-1]}_", f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}")
+ tkinter.messagebox.showinfo(title="提示", message="提取成功!")
+ except:
+ traceback.print_exc()
+ tkinter.messagebox.showerror(title="错误", message=traceback.format_exc())
+
+class ProgramSetting():
+ wineBottonA = None
+ wineDebug = None
+ defultWine = None
+ defultBotton = None
+ terminalOpen = None
+ wineOption = None
+ #wineBottonDifferent = None
+ centerWindow = None
+ message = None
+ def ShowWindow():
+ ProgramSetting.message = QtWidgets.QMainWindow()
+ widget = QtWidgets.QWidget()
+ widgetLayout = QtWidgets.QGridLayout()
+ widgetLayout.addWidget(QtWidgets.QLabel("选择 Wine 容器版本:"), 0, 0, 1, 1)
+ widgetLayout.addWidget(QtWidgets.QLabel("wine DEBUG 信息输出:"), 1, 0, 1, 1)
+ widgetLayout.addWidget(QtWidgets.QLabel("默认 Wine:"), 2, 0, 1, 1)
+ widgetLayout.addWidget(QtWidgets.QLabel("默认 Wine 容器:"), 3, 0, 1, 1)
+ widgetLayout.addWidget(QtWidgets.QLabel("使用终端打开:"), 4, 0, 1, 1)
+ widgetLayout.addWidget(QtWidgets.QLabel("自定义 wine 参数:"), 5, 0, 1, 1)
+ ProgramSetting.wineBottonA = QtWidgets.QComboBox()
+ ProgramSetting.wineDebug = QtWidgets.QCheckBox("开启 DEBUG 输出")
+ ProgramSetting.defultWine = QtWidgets.QComboBox()
+ ProgramSetting.defultBotton = QtWidgets.QLineEdit()
+ save = QtWidgets.QPushButton("保存")
+ save.clicked.connect(ProgramSetting.Save)
+ defultBottonButton = QtWidgets.QPushButton("浏览")
+ defultBottonButton.clicked.connect(ProgramSetting.Browser)
+ ProgramSetting.terminalOpen = QtWidgets.QCheckBox("使用终端打开(deepin 终端)")
+ ProgramSetting.wineOption = QtWidgets.QLineEdit()
+ ProgramSetting.wineBottonA.addItems(["Auto", "win32", "win64"])
+ ProgramSetting.wineBottonA.setCurrentText(setting["Architecture"])
+ ProgramSetting.wineDebug.setChecked(setting["Debug"])
+ ProgramSetting.defultWine.addItems(wine.keys())
+ ProgramSetting.defultWine.setCurrentText(setting["DefultWine"])
+ ProgramSetting.defultBotton.setText(setting["DefultBotton"])
+ ProgramSetting.terminalOpen.setChecked(setting["TerminalOpen"])
+ ProgramSetting.wineOption.setText(setting["WineOption"])
+ widgetLayout.addWidget(ProgramSetting.wineBottonA, 0, 1, 1, 1)
+ widgetLayout.addWidget(ProgramSetting.wineDebug, 1, 1, 1, 1)
+ widgetLayout.addWidget(ProgramSetting.defultWine, 2, 1, 1, 1)
+ widgetLayout.addWidget(ProgramSetting.defultBotton, 3, 1, 1, 1)
+ widgetLayout.addWidget(defultBottonButton, 3, 2, 1, 1)
+ widgetLayout.addWidget(ProgramSetting.terminalOpen, 4, 1, 1, 1)
+ widgetLayout.addWidget(ProgramSetting.wineOption, 5, 1, 1, 1)
+ widgetLayout.addWidget(save, 6, 2, 1, 1)
+ widget.setLayout(widgetLayout)
+ ProgramSetting.message.setCentralWidget(widget)
+ ProgramSetting.message.setWindowTitle(f"设置 wine 运行器 {version}")
+ #ProgramSetting.message.resize(ProgramSetting.message.frameSize().width() * 1.2, ProgramSetting.message.frameSize().height())
+ ProgramSetting.message.show()
+ return
+
+ def Browser():
+ path = QtWidgets.QFileDialog.getExistingDirectory(ProgramSetting.message, "选择 Wine 容器", json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBotton.json"))["path"])#tkinter.filedialog.askdirectory(title="选择 Wine 容器", initialdir=json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBotton.json"))["path"])
+ if path == "" or path == None or path == "()" or path == ():
+ return
+ ProgramSetting.defultBotton.setText(path)
+
+ def Save():
+ # 写入容器位数设置
+ setting["Architecture"] = ProgramSetting.wineBottonA.currentText()
+ setting["Debug"] = ProgramSetting.wineDebug.isChecked()
+ setting["DefultWine"] = ProgramSetting.defultWine.currentText()
+ setting["DefultBotton"] = ProgramSetting.defultBotton.text()
+ setting["TerminalOpen"] = ProgramSetting.terminalOpen.isChecked()
+ setting["WineOption"] = ProgramSetting.wineOption.text()
+ try:
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
+ except:
+ traceback.print_exc()
+ QtWidgets.QMessageBox.critical(ProgramSetting.message, "错误", traceback.format_exc())
+ return
+ QtWidgets.QMessageBox.information(ProgramSetting.message, "提示", "保存完毕!")
+
+###########################
+# 加载配置
+###########################
+defultProgramList = {
+ "Architecture": "Auto",
+ "Debug": True,
+ "DefultWine": "deepin-wine6 stable",
+ "DefultBotton" : get_home() + "/.wine",
+ "TerminalOpen": False,
+ "WineOption": "",
+ "WineBottonDifferent": False,
+ "CenterWindow": False
+}
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
+ os.mkdir(get_home() + "/.config/deepin-wine-runner") # 创建配置文件夹
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ShellHistory.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", json.dumps({})) # 创建配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", json.dumps({})) # 创建配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", json.dumps({})) # 创建配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPath.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", json.dumps({})) # 写入(创建)一个配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", json.dumps({})) # 写入(创建)一个配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExe.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindExe.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindISO.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/FindISO.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBotton.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineBotton.json", json.dumps({"path": "~/.deepinwine"})) # 写入(创建)一个配置文件
+if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineSetting.json"): # 如果没有配置文件
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(defultProgramList)) # 写入(创建)一个配置文件
+
+###########################
+# 设置变量
+###########################
+# 如果要添加其他 wine,请在字典添加其名称和执行路径
+try:
+ wine = {"deepin-wine": "deepin-wine", "deepin-wine5": "deepin-wine5", "wine": "wine", "wine64": "wine64", "deepin-wine5 stable": "deepin-wine5-stable", "deepin-wine6 stable": "deepin-wine6-stable", "spark-wine7-devel": "spark-wine7-devel", "ukylin-wine": "ukylin-wine"}
+ shellHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json")).values())
+ findExeHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json")).values())
+ wineBottonHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json")).values())
+ isoPath = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPath.json")).values())
+ isoPathFound = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json")).values())
+ setting = json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineSetting.json"))
+ change = False
+ for i in ["Architecture", "Debug", "DefultWine", "DefultBotton", "TerminalOpen", "WineOption", "WineBottonDifferent", "CenterWindow"]:
+ if not i in setting:
+ change = True
+ setting[i] = defultProgramList[i]
+ if change:
+ write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
+except:
+ root = tk.Tk()
+ root.withdraw()
+ tkinter.messagebox.showerror(title="错误", message="无法读取配置,无法继续")
+ sys.exit(1)
+
+###########################
+# 程序信息
+###########################
+programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
+iconPath = "{}/icon.png".format(programPath)
+programUrl = "https://gitee.com/gfdgd-xi/deep-wine-runner\nhttps://github.com/gfdgd-xi/deep-wine-runner\nhttps://www.gitlink.org.cn/gfdgd_xi/deep-wine-runner"
+information = json.loads(readtxt(f"{programPath}/information.json"))
+version = information["Version"]
+goodRunSystem = "Linux"
+thankText = ""
+tips = '''提示:
+1、使用终端运行该程序,可以看到 wine 以及程序本身的提示和报错;
+2、wine 32 位和 64 位的容器互不兼容;
+3、所有的 wine 和 winetricks 均需要自行安装(可以从 菜单栏=>程序 里面进行安装)
+4、本程序支持带参数运行 wine 程序(之前版本也可以),只需要按以下格式即可:
+exe路径\' 参数 \'
+即可(单引号需要输入)
+5、wine 容器如果没有指定,则会默认为 ~/.wine'''
+updateThingsString = '''※1、添加 @delsin 和 @神末shenmo 建议的 postrm 脚本
+2、将 pip 由阿里源改为华为源,提升下载速度
+3、优化多屏窗口居中问题,并设置居中选项为选开防止错误
+4、修复 1.6.0 程序无法保存设置的问题
+5、修复 1.6.0 的更新程序无法正常更新的问题
+6、界面大改造,从使用 Tkinter 改为 Qt,参考了 @134******28 和 @sgb76 提供的设计方案和代码
+7、添加了基于 UOS 生态适配活动打包脚本的打包器,以及基于 Virtualbox 的简易 Windows 镜像安装工具
+'''
+for i in information["Thank"]:
+ thankText += f"{i}\n"
+updateTime = "2022年07月18日"
+about = f'''
一个基于 Python3 的 tkinter 制作的 wine 运行器
+
+版本:{version}
+适用平台:{goodRunSystem}
+tkinter 版本:{tk.TkVersion}
+Qt 版本:{QtCore.qVersion()}
+程序官网:{programUrl}
+{thankText}
+{updateThingsString}
+更新时间:{updateTime}
+