mirror of
https://gitee.com/gfdgd-xi/deep-wine-runner
synced 2025-01-12 17:48:27 +08:00
1639 lines
78 KiB
Python
Executable File
1639 lines
78 KiB
Python
Executable File
#!/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"<img src='{iconPath}'>"), 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'''<h1>关于</h1>
|
||
<pre>一个基于 Python3 的 tkinter 制作的 wine 运行器
|
||
|
||
版本:{version}
|
||
适用平台:{goodRunSystem}
|
||
tkinter 版本:{tk.TkVersion}
|
||
Qt 版本:{QtCore.qVersion()}
|
||
程序官网:{programUrl}</pre>
|
||
<hr>
|
||
<h1>谢明名单</h1>
|
||
<pre>{thankText}</pre>
|
||
<hr>
|
||
<h1>更新内容</h1>
|
||
<pre>{updateThingsString}
|
||
<b>更新时间:{updateTime}</b></pre>
|
||
<hr>
|
||
<h1>©2020~{time.strftime("%Y")} gfdgd xi、为什么您不喜欢熊出没和阿布呢</h1>'''
|
||
title = "wine 运行器 {}".format(version)
|
||
updateThings = "{} 更新内容:\n{}\n更新时间:{}".format(version, updateThingsString, updateTime, time.strftime("%Y"))
|
||
|
||
|
||
###########################
|
||
# 窗口创建
|
||
###########################
|
||
# 因为没有完全改完,所以需要这些东西来兼容 tkinter 的主题
|
||
# 读取主题
|
||
try:
|
||
theme = not ("dark" in readtxt(get_home() + "/.gtkrc-2.0") and "gtk-theme-name=" in readtxt(get_home() + "/.gtkrc-2.0"))
|
||
except:
|
||
print("主题读取错误,默认使用浅色主题")
|
||
theme = True
|
||
if theme:
|
||
win = tk.Tk()
|
||
themes = ttkthemes.ThemedStyle(win)
|
||
themes.set_theme("breeze")
|
||
else:
|
||
import ttkbootstrap
|
||
style = ttkbootstrap.Style(theme="darkly")
|
||
win = style.master # 创建窗口
|
||
win.withdraw() # 不显示 tkinter 根窗口
|
||
# Qt 窗口
|
||
app = QtWidgets.QApplication(sys.argv)
|
||
window = QtWidgets.QMainWindow()
|
||
widget = QtWidgets.QWidget()
|
||
window.setCentralWidget(widget)
|
||
mainLayout = QtWidgets.QGridLayout()
|
||
# 权重
|
||
size = QtWidgets.QSizePolicy()
|
||
size.setHorizontalPolicy(0)
|
||
widgetSize = QtWidgets.QSizePolicy()
|
||
#size.setHorizontalPolicy(0)
|
||
widgetSize.setVerticalPolicy(0)
|
||
#
|
||
leftUp = QtWidgets.QWidget()
|
||
mainLayout.addWidget(leftUp, 0, 0, 1, 1)
|
||
leftUpLayout = QtWidgets.QGridLayout()
|
||
leftUp.setLayout(leftUpLayout)
|
||
fastLabel = QtWidgets.QLabel("快速启动")
|
||
fastLabel.setStyleSheet("font: 30px;")
|
||
leftUpLayout.addWidget(fastLabel, 0, 0, 1, 2)
|
||
leftUpLayout.addWidget(QtWidgets.QLabel("<hr>"), 1, 0, 1, 2)
|
||
leftUpLayout.addWidget(QtWidgets.QLabel("请选择容器路径:"), 2, 0, 1, 1)
|
||
e1 = QtWidgets.QComboBox()
|
||
e1.setEditable(True)
|
||
leftUpLayout.addWidget(e1, 3, 0, 1, 1)
|
||
button1 = QtWidgets.QPushButton("浏览")
|
||
button1.clicked.connect(liulanbutton)
|
||
leftUpLayout.addWidget(button1, 3, 1, 1, 1)
|
||
leftUpLayout.addWidget(QtWidgets.QLabel("请选择要执行的程序:"), 4, 0, 1, 1)
|
||
e2 = QtWidgets.QComboBox()
|
||
e2.setEditable(True)
|
||
leftUpLayout.addWidget(e2, 5, 0, 1, 1)
|
||
button2 = QtWidgets.QPushButton("浏览")
|
||
button2.clicked.connect(liulanexebutton)
|
||
leftUpLayout.addWidget(button2, 5, 1, 1, 1)
|
||
leftUpLayout.addWidget(QtWidgets.QLabel("请选择WINE版本:"), 6, 0, 1, 1)
|
||
o1 = QtWidgets.QComboBox()
|
||
leftUpLayout.addWidget(o1, 7, 0, 1, 1)
|
||
# 设置空间权重
|
||
button1.setSizePolicy(size)
|
||
button2.setSizePolicy(size)
|
||
|
||
|
||
leftDown = QtWidgets.QWidget()
|
||
mainLayout.addWidget(leftDown, 1, 0, 1, 1)
|
||
leftDownLayout = QtWidgets.QVBoxLayout()
|
||
leftDown.setLayout(leftDownLayout)
|
||
highLabel = QtWidgets.QLabel("高级功能")
|
||
highLabel.setStyleSheet("font: 30px;")
|
||
leftDownLayout.addWidget(highLabel)
|
||
leftDownLayout.addWidget(QtWidgets.QLabel("<hr>"))
|
||
leftDownLayout.addWidget(QtWidgets.QLabel("创建快捷方式(Desktop文件):"))
|
||
createDesktopLink = QtWidgets.QHBoxLayout()
|
||
label_r_2 = QtWidgets.QLabel("名称:")
|
||
createDesktopLink.addWidget(label_r_2)
|
||
combobox1 = QtWidgets.QComboBox()
|
||
combobox1.setEditable(True)
|
||
createDesktopLink.addWidget(combobox1)
|
||
button5 = QtWidgets.QPushButton("创建到桌面")
|
||
button5.clicked.connect(make_desktop_on_desktop)
|
||
createDesktopLink.addWidget(button5)
|
||
saveDesktopFileOnLauncher = QtWidgets.QPushButton("创建到开始菜单")
|
||
saveDesktopFileOnLauncher.clicked.connect(make_desktop_on_launcher)
|
||
createDesktopLink.addWidget(saveDesktopFileOnLauncher)
|
||
leftDownLayout.addLayout(createDesktopLink)
|
||
programManager = QtWidgets.QGridLayout()
|
||
leftDownLayout.addLayout(programManager)
|
||
programManager.addWidget(QtWidgets.QLabel("程序管理:"), 0, 0, 1, 1)
|
||
getProgramIcon = QtWidgets.QPushButton("提取图标")
|
||
getProgramIcon.clicked.connect(lambda: RunWineProgram(f"{programPath}/BeCyIconGrabber.exe"))
|
||
programManager.addWidget(getProgramIcon, 1, 0, 1, 1)
|
||
programManager.addWidget(QtWidgets.QLabel(" "*5), 1, 1, 1, 1)
|
||
trasButton = QtWidgets.QPushButton("窗口透明工具")
|
||
trasButton.clicked.connect(lambda: RunWineProgram(f"{programPath}/窗体透明度设置工具.exe"))
|
||
programManager.addWidget(trasButton, 1, 2, 1, 1)
|
||
uninstallProgram = QtWidgets.QPushButton("卸载程序")
|
||
uninstallProgram.clicked.connect(lambda: RunWineProgram(f"{programPath}/geek.exe"))
|
||
programManager.addWidget(QtWidgets.QLabel(" "*5), 1, 3, 1, 1)
|
||
programManager.addWidget(uninstallProgram, 1, 4, 1, 1)
|
||
programManager.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum), 1, 5, 1, 1)
|
||
programManager.addWidget(QtWidgets.QLabel("WINE配置:"), 2, 0, 1, 1)
|
||
wineConfig = QtWidgets.QPushButton("配置容器")
|
||
wineConfig.clicked.connect(lambda: RunWineProgram("winecfg"))
|
||
programManager.addWidget(wineConfig, 3, 0, 1, 1)
|
||
button_r_6 = QtWidgets.QPushButton("安装字体")
|
||
button_r_6.clicked.connect(OpenWineFontPath)
|
||
programManager.addWidget(button_r_6, 3, 2, 1, 1)
|
||
sparkWineSetting = QtWidgets.QPushButton("星火wine配置")
|
||
sparkWineSetting.clicked.connect(lambda: threading.Thread(target=os.system, args=["/opt/durapps/spark-dwine-helper/spark-dwine-helper-settings/settings.sh"]).start())
|
||
programManager.addWidget(sparkWineSetting, 3, 4, 1, 1)
|
||
# 权重
|
||
button5.setSizePolicy(size)
|
||
saveDesktopFileOnLauncher.setSizePolicy(size)
|
||
label_r_2.setSizePolicy(size)
|
||
getProgramIcon.setSizePolicy(size)
|
||
trasButton.setSizePolicy(size)
|
||
#uninstallProgram.setSizePolicy(size)
|
||
wineConfig.setSizePolicy(size)
|
||
|
||
returnText = QtWidgets.QTextBrowser()
|
||
returnText.setStyleSheet("""
|
||
background-color: black;
|
||
color: white;
|
||
""")
|
||
returnText.setText("在此可以看到wine安装应用时的终端输出内容")
|
||
mainLayout.setRowStretch(0, 2)
|
||
mainLayout.setRowStretch(1, 1)
|
||
mainLayout.setColumnStretch(0, 2)
|
||
mainLayout.setColumnStretch(1, 1)
|
||
mainLayout.addWidget(returnText, 0, 1, 2, 1)
|
||
|
||
# 版权
|
||
copy = QtWidgets.QLabel(f"""\n程序版本:{version}
|
||
©2020~{time.strftime("%Y")} gfdgd xi、为什么您不喜欢熊出没和阿布呢""")
|
||
mainLayout.addWidget(copy, 2, 0, 1, 1)
|
||
|
||
# 程序运行
|
||
programRun = QtWidgets.QWidget()
|
||
programRunLayout = QtWidgets.QHBoxLayout()
|
||
programRun.setLayout(programRunLayout)
|
||
programRunLayout.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum))
|
||
button3 = QtWidgets.QPushButton("运行程序")
|
||
button3.clicked.connect(runexebutton)
|
||
programRunLayout.addWidget(button3)
|
||
killProgram = QtWidgets.QPushButton("终止程序")
|
||
killProgram.clicked.connect(KillProgram)
|
||
programRunLayout.addWidget(killProgram)
|
||
mainLayout.addWidget(programRun, 2, 1, 1, 1)
|
||
|
||
# 菜单栏
|
||
menu = window.menuBar()
|
||
programmenu = menu.addMenu("程序(&P)")
|
||
p1 = QtWidgets.QAction("安装 wine(&I)")
|
||
p2 = QtWidgets.QAction("设置程序(&S)")
|
||
p3 = QtWidgets.QAction("清空软件历史记录(&C)")
|
||
p4 = QtWidgets.QAction("退出程序(&E)")
|
||
programmenu.addAction(p1)
|
||
programmenu.addSeparator()
|
||
programmenu.addAction(p2)
|
||
programmenu.addAction(p3)
|
||
programmenu.addSeparator()
|
||
programmenu.addAction(p4)
|
||
p1.triggered.connect(InstallWine)
|
||
p2.triggered.connect(ProgramSetting.ShowWindow)
|
||
p3.triggered.connect(CleanProgramHistory)
|
||
p4.triggered.connect(window.close)
|
||
|
||
wineOption = menu.addMenu("Wine(&W)")
|
||
w1 = QtWidgets.QAction("打开 Wine 容器目录")
|
||
w2 = QtWidgets.QAction("安装常见字体")
|
||
w3 = QtWidgets.QAction("安装自定义字体")
|
||
w4 = QtWidgets.QAction("删除选择的 Wine 容器")
|
||
w5 = QtWidgets.QAction("打包 wine 应用")
|
||
w6 = QtWidgets.QAction("使用官方 Wine 适配活动的脚本进行打包(测试只支持UOS)")
|
||
w7 = QtWidgets.QAction("从镜像获取DLL(只支持Windows XP、Windows Server 2003官方安装镜像)")
|
||
wineOption.addAction(w1)
|
||
wineOption.addAction(w2)
|
||
wineOption.addAction(w3)
|
||
wineOption.addAction(w4)
|
||
wineOption.addSeparator()
|
||
wineOption.addAction(w5)
|
||
wineOption.addAction(w6)
|
||
wineOption.addSeparator()
|
||
wineOption.addAction(w7)
|
||
wm1 = wineOption.addMenu("在指定 Wine、容器安装组件")
|
||
wm1_1 = QtWidgets.QAction("在指定wine、指定容器安装 .net framework")
|
||
wm1_2 = QtWidgets.QAction("在指定wine、指定容器安装 Visual Studio C++")
|
||
wm1_3 = QtWidgets.QAction("在指定wine、指定容器安装 MSXML")
|
||
wm1_4 = QtWidgets.QAction("在指定wine、指定容器安装 gecko")
|
||
wm1_5 = QtWidgets.QAction("在指定wine、指定容器安装 mono")
|
||
wm1_6 = QtWidgets.QAction("在指定wine、指定容器安装其它运行库")
|
||
wm1.addAction(wm1_1)
|
||
wm1.addAction(wm1_2)
|
||
wm1.addAction(wm1_3)
|
||
wm1.addAction(wm1_4)
|
||
wm1.addAction(wm1_5)
|
||
wm1.addAction(wm1_6)
|
||
wm2 = wineOption.addMenu("在指定 Wine、容器运行基础应用")
|
||
wm2_1 = QtWidgets.QAction("打开指定wine、指定容器的控制面板")
|
||
wm2_2 = QtWidgets.QAction("打开指定wine、指定容器的浏览器")
|
||
wm2_3 = QtWidgets.QAction("打开指定wine、指定容器的注册表")
|
||
wm2_4 = QtWidgets.QAction("打开指定wine、指定容器的任务管理器")
|
||
wm2_5 = QtWidgets.QAction("打开指定wine、指定容器的资源管理器")
|
||
wm2_6 = QtWidgets.QAction("打开指定wine、指定容器的关于 wine")
|
||
wm2.addAction(wm2_1)
|
||
wm2.addAction(wm2_2)
|
||
wm2.addAction(wm2_3)
|
||
wm2.addAction(wm2_4)
|
||
wm2.addAction(wm2_5)
|
||
wm2.addAction(wm2_6)
|
||
wineOption.addSeparator()
|
||
w8 = QtWidgets.QAction("设置 run_v3.sh 的文管为 Deepin 默认文管")
|
||
w9 = QtWidgets.QAction("设置 run_v3.sh 的文管为 Wine 默认文管")
|
||
w10 = QtWidgets.QAction("重新安装 deepin-wine-helper")
|
||
w11 = QtWidgets.QAction("使用winetricks打开指定容器")
|
||
wineOption.addAction(w8)
|
||
wineOption.addAction(w9)
|
||
wineOption.addAction(w10)
|
||
wineOption.addSeparator()
|
||
wineOption.addAction(w11)
|
||
wineOption.addSeparator()
|
||
wm3 = wineOption.addMenu("启用/禁用 opengl")
|
||
wm3_1 = QtWidgets.QAction("开启 opengl")
|
||
wm3_2 = QtWidgets.QAction("禁用 opengl")
|
||
wm3.addAction(wm3_1)
|
||
wm3.addAction(wm3_2)
|
||
wm4 = wineOption.addMenu("安装/卸载 winbind")
|
||
wm4_1 = QtWidgets.QAction("安装 winbind")
|
||
wm4_2 = QtWidgets.QAction("卸载 winbind")
|
||
wm4.addAction(wm4_1)
|
||
wm4.addAction(wm4_2)
|
||
w1.triggered.connect(OpenWineBotton)
|
||
w2.triggered.connect(InstallWineFont)
|
||
w3.triggered.connect(OpenWineFontPath)
|
||
w4.triggered.connect(DeleteWineBotton)
|
||
w5.triggered.connect(BuildExeDeb)
|
||
w6.triggered.connect(UOSPackageScript)
|
||
w7.triggered.connect(GetDllFromWindowsISO.ShowWindow)
|
||
w8.triggered.connect(SetDeepinFileDialogDeepin)
|
||
w9.triggered.connect(SetDeepinFileDialogDefult)
|
||
w10.triggered.connect(SetDeepinFileDialogRecovery)
|
||
w11.triggered.connect(lambda: RunWinetricks())
|
||
wm1_1.triggered.connect(lambda: threading.Thread(target=InstallNetFramework).start())
|
||
wm1_2.triggered.connect(lambda: threading.Thread(target=InstallVisualStudioCPlusPlus).start())
|
||
wm1_3.triggered.connect(lambda: threading.Thread(target=InstallMSXML).start())
|
||
wm1_4.triggered.connect(lambda: threading.Thread(target=InstallMonoGecko, args=["gecko"]).start())
|
||
wm1_5.triggered.connect(lambda: threading.Thread(target=InstallMonoGecko, args=["mono"]).start())
|
||
wm1_6.triggered.connect(lambda: threading.Thread(target=InstallOther).start())
|
||
wm2_1.triggered.connect(lambda: RunWineProgram("control"))
|
||
wm2_2.triggered.connect(lambda: RunWineProgram("iexplore' 'https://www.deepin.org"))
|
||
wm2_3.triggered.connect(lambda: RunWineProgram("regedit"))
|
||
wm2_4.triggered.connect(lambda: RunWineProgram("taskmgr"))
|
||
wm2_5.triggered.connect(lambda: RunWineProgram("explorer"))
|
||
wm2_6.triggered.connect(lambda: RunWineProgram("winver"))
|
||
wm3_1.triggered.connect(lambda: RunWineProgram(f"regedit.exe' /s '{programPath}/EnabledOpengl.reg"))
|
||
wm3_2.triggered.connect(lambda: RunWineProgram(f"regedit.exe' /s '{programPath}/DisabledOpengl.reg"))
|
||
wm4_1.triggered.connect(lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec apt install winbind -y' --keep-open"))
|
||
wm4_2.triggered.connect(lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec apt purge winbind -y' --keep-open"))
|
||
|
||
virtualMachine = menu.addMenu("虚拟机(&V)")
|
||
v1 = QtWidgets.QAction("使用 Virtualbox 虚拟机运行 Windows 应用")
|
||
virtualMachine.addAction(v1)
|
||
v1.triggered.connect(RunVM)
|
||
|
||
safeWebsize = menu.addMenu("云沙箱(&C)")
|
||
s1 = QtWidgets.QAction("360 沙箱云")
|
||
s2 = QtWidgets.QAction("微步云沙箱")
|
||
s3 = QtWidgets.QAction("VIRUSTOTAL")
|
||
safeWebsize.addAction(s1)
|
||
safeWebsize.addAction(s2)
|
||
safeWebsize.addAction(s3)
|
||
s1.triggered.connect(lambda: webbrowser.open_new_tab("https://ata.360.net/"))
|
||
s2.triggered.connect(lambda: webbrowser.open_new_tab("https://s.threatbook.cn/"))
|
||
s3.triggered.connect(lambda: webbrowser.open_new_tab("https://www.virustotal.com/"))
|
||
|
||
help = menu.addMenu("帮助(&H)")
|
||
h1 = QtWidgets.QAction("程序官网")
|
||
h2 = QtWidgets.QAction("小提示")
|
||
h3 = QtWidgets.QAction("更新内容")
|
||
h4 = QtWidgets.QAction("谢明名单")
|
||
h5 = QtWidgets.QAction("更新这个程序")
|
||
h6 = QtWidgets.QAction("反馈这个程序的建议和问题")
|
||
h7 = QtWidgets.QAction("关于这个程序")
|
||
h8 = QtWidgets.QAction("关于 Qt")
|
||
help.addAction(h1)
|
||
help.addSeparator()
|
||
help.addAction(h2)
|
||
help.addAction(h3)
|
||
help.addAction(h4)
|
||
help.addSeparator()
|
||
help.addAction(h5)
|
||
help.addAction(h6)
|
||
help.addAction(h7)
|
||
help.addAction(h8)
|
||
help.addSeparator()
|
||
hm1 = help.addMenu("更多生态适配应用")
|
||
hm1_1 = QtWidgets.QAction("运行 Android 应用:UEngine 运行器")
|
||
hm1.addAction(hm1_1)
|
||
h1.triggered.connect(OpenProgramURL)
|
||
h2.triggered.connect(helps)
|
||
h3.triggered.connect(UpdateThings)
|
||
h4.triggered.connect(ThankWindow)
|
||
h5.triggered.connect(UpdateWindow.ShowWindow)
|
||
h6.triggered.connect(WineRunnerBugUpload)
|
||
h7.triggered.connect(about_this_program)
|
||
h8.triggered.connect(lambda: QtWidgets.QMessageBox.aboutQt(widget))
|
||
hm1_1.triggered.connect(lambda: webbrowser.open_new_tab("https://gitee.com/gfdgd-xi/uengine-runner"))
|
||
|
||
# 窗口设置
|
||
window.resize(widget.frameGeometry().width() * 2, widget.frameGeometry().height())
|
||
widget.setLayout(mainLayout)
|
||
window.setWindowTitle(title)
|
||
window.setWindowIcon(QtGui.QIcon(f"{programPath}/icon.png"))
|
||
widget.show()
|
||
window.show()
|
||
|
||
# 控件设置
|
||
e1.addItems(findExeHistory)
|
||
e2.addItems(wineBottonHistory)
|
||
combobox1.addItems(shellHistory)
|
||
o1.addItems(wine.keys())
|
||
o1.setCurrentText(setting["DefultWine"])
|
||
e1.setEditText(setting["DefultBotton"])
|
||
e2.setEditText("")
|
||
combobox1.setEditText("")
|
||
if len(sys.argv) > 1 and sys.argv[1]:
|
||
e2.setEditText(sys.argv[1])
|
||
if not os.path.exists("/opt/durapps/spark-dwine-helper/spark-dwine-helper-settings/settings.sh"):
|
||
sparkWineSetting.setEnabled(False)
|
||
sys.exit(app.exec_())
|
||
|
||
# 读取主题
|
||
try:
|
||
theme = not ("dark" in readtxt(get_home() + "/.gtkrc-2.0") and "gtk-theme-name=" in readtxt(get_home() + "/.gtkrc-2.0"))
|
||
except:
|
||
print("主题读取错误,默认使用浅色主题")
|
||
theme = True
|
||
if theme:
|
||
style = ttkbootstrap.Style(theme="litera")
|
||
win = style.master # 创建窗口
|
||
else:
|
||
style = ttkbootstrap.Style(theme="darkly")
|
||
win = style.master # 创建窗口
|
||
|
||
win.title(title) # 设置标题
|
||
#root.geometry("1275x900")
|
||
# 设置变量以修改和获取值项
|
||
o1_text = tk.StringVar()
|
||
combobox1 = tk.StringVar()
|
||
o1_text.set("deepin-wine6 stable")
|
||
frame_up = ttk.Frame(win)
|
||
|
||
frame_left = tk.Frame(frame_up)#快速启动区
|
||
frame_left.config(bd=30)
|
||
#
|
||
frame_left_1 = ttk.Frame(frame_left)#左侧标题
|
||
left_title = ttk.Label(frame_left_1,text="快速启动")
|
||
left_title.config(font=("幼圆",24))
|
||
left_title.pack(anchor="w")
|
||
frame_left_1.grid(row=0,sticky="w" + "e")
|
||
#
|
||
frame_left_2 = ttk.Frame(frame_left)#容器路径
|
||
##
|
||
label_l_1 = ttk.Label(frame_left_2,text="请选择容器的路径:")
|
||
label_l_1.config(font=("幼圆",16))
|
||
label_l_1.grid(row=0,column=0,sticky='w')
|
||
##
|
||
e1 = ttk.Combobox(frame_left_2, width=65)
|
||
e1.grid(row=1,column=0)
|
||
##
|
||
button1 = tk.Button(frame_left_2,text="浏览", command=liulanbutton)
|
||
button1.config(font=("幼圆",12),padx=20,pady=3)
|
||
button1.grid(row=1,column=1)
|
||
##
|
||
frame_left_2.grid(row=1)
|
||
#
|
||
frame_left_3 = ttk.Frame(frame_left)#程序路径
|
||
label_l_2 = ttk.Label(frame_left_3,text="请选择待执行程序:")
|
||
label_l_2.config(font=("幼圆",16))
|
||
label_l_2.grid(row=0,column=0,sticky='w')
|
||
##
|
||
e2 = ttk.Combobox(frame_left_3, width=65)
|
||
e2.grid(row=1,column=0)
|
||
##
|
||
button2 = tk.Button(frame_left_3,text="浏览", command=liulanexebutton)
|
||
button2.config(font=("幼圆",12),padx=20,pady=3)
|
||
button2.grid(row=1,column=1)
|
||
##
|
||
frame_left_3.grid(row=2)
|
||
#
|
||
frame_left_4 = ttk.Frame(frame_left)#wine的版本
|
||
##
|
||
label_l_3 = ttk.Label(frame_left_4,text="请选择wine的版本")
|
||
label_l_3.config(font=("幼圆",16))
|
||
label_l_3.grid(row=0,column=0,sticky='w')
|
||
##
|
||
o1 = ttk.OptionMenu(frame_left_4, o1_text, setting["DefultWine"], *list(wine))
|
||
o1.grid(row=1,column=0)
|
||
##
|
||
label_l_4 = ttk.Label(frame_left_4,text=" "*4)#占位用字符串
|
||
label_l_4.grid(row=1,column=1)
|
||
##
|
||
button3 = tk.Button(frame_left_4,text="运行程序", command=runexebutton)
|
||
button3.config(font=("幼圆",12),padx=21,pady=3)
|
||
button3.grid(row=1,column=2)
|
||
##
|
||
label_l_5 = ttk.Label(frame_left_4,text=" "*13)#占位用字符串
|
||
label_l_5.grid(row=1,column=3)
|
||
##
|
||
killProgram = tk.Button(frame_left_4,text="终止程序", command=KillProgram)
|
||
killProgram.config(font=("幼圆",12),padx=21,pady=3)
|
||
killProgram.grid(row=1,column=4)
|
||
##
|
||
frame_left_4.grid(row=3)
|
||
#
|
||
frame_left.grid(row=0,column=0)#第一行第一列
|
||
|
||
frame_right = tk.Frame(frame_up)#高级配置区
|
||
frame_right.config(bd=30)
|
||
#
|
||
frame_right_1 = ttk.Frame(frame_right)
|
||
right_title = ttk.Label(frame_right_1,text="高级功能")
|
||
right_title.config(font=("幼圆",24))
|
||
right_title.pack(anchor="w")
|
||
frame_right_1.grid(row=0,sticky="w" + "e")
|
||
#
|
||
frame_right_2 = tk.Frame(frame_right)
|
||
##
|
||
label_r_1 = ttk.Label(frame_right_2,text="创建快捷方式(Desktop文件):")
|
||
label_r_1.config(font=("幼圆",16))
|
||
label_r_1.grid(row=0,column=0)
|
||
##
|
||
frame_right_2.grid(row=1,sticky='w')
|
||
#
|
||
frame_right_3 = tk.Frame(frame_right)
|
||
##
|
||
label_r_2 = ttk.Label(frame_right_3,text="名称:")
|
||
label_r_2.config(font=("幼圆",14))
|
||
label_r_2.grid(row=0,column=0)
|
||
##
|
||
combobox1 = ttk.Combobox(frame_right_3,width=20)
|
||
combobox1.grid(row=0,column=1)
|
||
##
|
||
empty1 = ttk.Label(frame_right_3,text=" "*5)
|
||
empty1.grid(row=0,column=2)
|
||
##
|
||
button5 = tk.Button(frame_right_3,text="创建到桌面", command=make_desktop_on_desktop)
|
||
button5.config(font=("幼圆",12),padx=20,pady=3)
|
||
button5.grid(row=0,column=3)
|
||
##
|
||
empty2 = ttk.Label(frame_right_3,text=" "*5)
|
||
empty2.grid(row=0,column=4)
|
||
##
|
||
saveDesktopFileOnLauncher = tk.Button(frame_right_3,text="创建到开始菜单", command=make_desktop_on_launcher)
|
||
saveDesktopFileOnLauncher.config(font=("幼圆",12),padx=20,pady=3)
|
||
saveDesktopFileOnLauncher.grid(row=0,column=5)
|
||
##
|
||
frame_right_3.grid(row=2,sticky='w')
|
||
#
|
||
frame_right_4 = ttk.Frame(frame_right)
|
||
##
|
||
label_r_2 = ttk.Label(frame_right_4,text="管理该程序:")
|
||
label_r_2.config(font=("幼圆",16))
|
||
label_r_2.grid(row=0,column=0)
|
||
##
|
||
frame_right_4.grid(row=3,sticky='w')
|
||
#
|
||
frame_right_5 = ttk.Frame(frame_right)
|
||
##
|
||
uninstallProgram = tk.Button(frame_right_5,text="卸载程序", command=UninstallProgram)
|
||
uninstallProgram.config(font=("幼圆",12),padx=20,pady=3)
|
||
uninstallProgram.grid(column=0)
|
||
##
|
||
empty3 = ttk.Label(frame_right_5,text=" "*5)
|
||
empty3.grid(row=0,column=1)
|
||
##
|
||
getProgramIcon = tk.Button(frame_right_5,text="提取图标", command=lambda: threading.Thread(target=RunWineProgram, args=[f"{programPath}/BeCyIconGrabber.exe"]).start())
|
||
getProgramIcon.config(font=("幼圆",12),padx=20,pady=3)
|
||
getProgramIcon.grid(row=0,column=2)
|
||
##
|
||
empty6 = ttk.Label(frame_right_5,text=" "*5)
|
||
empty6.grid(row=0,column=3)
|
||
##
|
||
trasButton = tk.Button(frame_right_5,text="窗口透明度工具", command=lambda: threading.Thread(target=RunWineProgram, args=[programPath + "/窗体透明度设置工具.exe"]).start())
|
||
trasButton.config(font=("幼圆",12),padx=20,pady=3)
|
||
trasButton.grid(row=0,column=4)
|
||
##
|
||
frame_right_5.grid(row=4,sticky='w')
|
||
#
|
||
frame_right_6 = ttk.Frame(frame_right)
|
||
##
|
||
label_r_3 = ttk.Label(frame_right_6,text="管理该wine")
|
||
label_r_3.config(font=("幼圆",16))
|
||
label_r_3.grid(row=0,column=0)
|
||
##
|
||
frame_right_6.grid(row=5,sticky='w')
|
||
#
|
||
frame_right_7 = ttk.Frame(frame_right)
|
||
##
|
||
wineConfig = tk.Button(frame_right_7,text="配置容器", command=ConfigWineBotton)
|
||
wineConfig.config(font=("幼圆",12),padx=20,pady=3)
|
||
wineConfig.grid(row=0,column=0)
|
||
##
|
||
empty4 = ttk.Label(frame_right_7,text=" "*5)
|
||
empty4.grid(row=0,column=1)
|
||
##
|
||
button_r_6 = tk.Button(frame_right_7,text="安装字体", command=OpenWineFontPath)
|
||
button_r_6.config(font=("幼圆",12),padx=20,pady=3)
|
||
button_r_6.grid(row=0,column=2)
|
||
##
|
||
empty5 = ttk.Label(frame_right_7,text=" "*5)
|
||
empty5.grid(row=0,column=3)
|
||
##
|
||
sparkWineSetting = tk.Button(frame_right_7,text="星火wine设置", command=lambda: threading.Thread(target=os.system, args=["/opt/durapps/spark-dwine-helper/spark-dwine-helper-settings/settings.sh"]).start())
|
||
sparkWineSetting.config(font=("幼圆",12),padx=20,pady=3)
|
||
sparkWineSetting.grid(row=0,column=4)
|
||
##
|
||
frame_right_7.grid(row=6,sticky='w')
|
||
#
|
||
frame_right.grid(row=0,column=1,sticky='n')#第一行第二列
|
||
|
||
frame_up.grid(row=0,sticky='w')
|
||
|
||
frame_down = tk.Frame(win,bd=30)
|
||
returnText = tk.Text(frame_down,width=120, height=15)
|
||
returnText.insert("end", "此可以查看到 Wine 应用安装时的程序返回值")
|
||
returnText.config(state=tk.DISABLED)
|
||
returnText.grid(row=0,column=0,sticky='e'+'w')
|
||
frame_down.grid(row=1,sticky='w')
|
||
|
||
menu = tk.Menu(win, background="white") # 设置菜单栏
|
||
programmenu = tk.Menu(menu, tearoff=0, background="white") # 设置“程序”菜单栏
|
||
menu.add_cascade(label="程序", menu=programmenu)
|
||
programmenu.add_command(label="安装 wine", command=InstallWine)
|
||
programmenu.add_separator() # 设置分界线
|
||
programmenu.add_command(label="设置程序", command=ProgramSetting.ShowWindow)
|
||
programmenu.add_command(label="清空软件历史记录", command=CleanProgramHistory)
|
||
programmenu.add_separator() # 设置分界线
|
||
programmenu.add_command(label="退出程序", command=win.quit) # 设置“退出程序”项
|
||
wineOption = tk.Menu(menu, tearoff=0, background="white") # 设置“Wine”菜单栏
|
||
menu.add_cascade(label="Wine", menu=wineOption)
|
||
wineOption.add_command(label="打开 Wine 容器目录", command=OpenWineBotton)
|
||
wineOption.add_command(label="安装常见字体", command=InstallWineFont)
|
||
wineOption.add_command(label="安装自定义字体", command=OpenWineFontPath)
|
||
wineOption.add_command(label="删除选择的 Wine 容器", command=DeleteWineBotton)
|
||
wineOption.add_separator()
|
||
wineOption.add_command(label="打包 wine 应用", command=BuildExeDeb)
|
||
wineOption.add_command(label="使用官方 Wine 适配活动的脚本进行打包(测试只支持UOS)", command=UOSPackageScript)
|
||
wineOption.add_separator()
|
||
wineOption.add_command(label="从镜像获取DLL(只支持Windows XP、Windows Server 2003官方安装镜像)", command=GetDllFromWindowsISO.ShowWindow)
|
||
wineOption.add_separator()
|
||
wineInstall = tk.Menu()
|
||
wineOption.add_cascade(label="在指定 Wine、容器安装组件", menu=wineInstall)
|
||
wineInstall.add_command(label="在指定wine、指定容器安装 .net framework", command=lambda: threading.Thread(target=InstallNetFramework).start())
|
||
wineInstall.add_command(label="在指定wine、指定容器安装 Visual Studio C++", command=lambda: threading.Thread(target=InstallVisualStudioCPlusPlus).start())
|
||
wineInstall.add_command(label="在指定wine、指定容器安装 MSXML", command=lambda: threading.Thread(target=InstallMSXML).start())
|
||
wineInstall.add_command(label="在指定wine、指定容器安装 gecko", command=lambda: threading.Thread(target=InstallMonoGecko, args=["gecko"]).start())
|
||
wineInstall.add_command(label="在指定wine、指定容器安装 mono", command=lambda: threading.Thread(target=InstallMonoGecko, args=["mono"]).start())
|
||
wineInstall.add_command(label="在指定wine、指定容器安装其它运行库", command=lambda: threading.Thread(target=InstallOther).start())
|
||
wineDefultMenu = tk.Menu()
|
||
wineOption.add_cascade(label="在指定 Wine、容器运行基础应用", menu=wineDefultMenu)
|
||
wineDefultMenu.add_command(label="打开指定wine、指定容器的控制面板", command=lambda: threading.Thread(target=RunWineProgram, args=["control"]).start())
|
||
wineDefultMenu.add_command(label="打开指定wine、指定容器的浏览器", command=lambda: threading.Thread(target=RunWineProgram, args=["iexplore' 'https://www.deepin.org"]).start())
|
||
wineDefultMenu.add_command(label="打开指定wine、指定容器的注册表", command=lambda: threading.Thread(target=RunWineProgram, args=["regedit"]).start())
|
||
wineDefultMenu.add_command(label="打开指定wine、指定容器的任务管理器", command=lambda: threading.Thread(target=RunWineProgram, args=["taskmgr"]).start())
|
||
wineDefultMenu.add_command(label="打开指定wine、指定容器的资源管理器", command=lambda: threading.Thread(target=RunWineProgram, args=["explorer"]).start())
|
||
wineDefultMenu.add_command(label="打开指定wine、指定容器的关于 wine", command=lambda: threading.Thread(target=RunWineProgram, args=["winver"]).start())
|
||
wineOption.add_separator()
|
||
wineOption.add_command(label="设置 run_v3.sh 的文管为 Deepin 默认文管", command=SetDeepinFileDialogDeepin)
|
||
wineOption.add_command(label="设置 run_v3.sh 的文管为 Wine 默认文管", command=SetDeepinFileDialogDefult)
|
||
wineOption.add_command(label="重新安装 deepin-wine-helper", command=SetDeepinFileDialogRecovery)
|
||
wineOption.add_separator()
|
||
wineOption.add_command(label="使用winetricks打开指定容器", command=lambda: threading.Thread(target=RunWinetricks).start())
|
||
wineOption.add_separator()
|
||
opengl = tk.Menu()
|
||
opengl.add_command(label="开启 opengl", command=lambda: threading.Thread(target=RunWineProgram, args=[f"regedit.exe' /s '{programPath}/EnabledOpengl.reg"]).start())
|
||
opengl.add_command(label="禁用 opengl", command=lambda: threading.Thread(target=RunWineProgram, args=[f"regedit.exe' /s '{programPath}/DisabledOpengl.reg"]).start())
|
||
wineOption.add_cascade(label="启用/禁用 opengl", menu=opengl)
|
||
winbind = tk.Menu()
|
||
winbind.add_command(label="安装 winbind", command=lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec apt install winbind -y' --keep-open"))
|
||
winbind.add_command(label="卸载 winbind", command=lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec apt purge winbind -y' --keep-open"))
|
||
wineOption.add_cascade(label="安装/卸载 winbind", menu=winbind)
|
||
virtualMachine = tk.Menu(menu, tearoff=0, background="white")
|
||
menu.add_cascade(label="虚拟机", menu=virtualMachine)
|
||
virtualMachine.add_command(label="使用 Virtualbox 虚拟机运行 Windows 应用", command=RunVM)
|
||
safeWebsize = tk.Menu(menu, tearoff=0, background="white")
|
||
menu.add_cascade(label="云沙箱", menu=safeWebsize)
|
||
safeWebsize.add_command(label="360 沙箱云", command=lambda: webbrowser.open_new_tab("https://ata.360.net/"))
|
||
safeWebsize.add_command(label="微步云沙箱", command=lambda: webbrowser.open_new_tab("https://s.threatbook.cn/"))
|
||
safeWebsize.add_command(label="VIRUSTOTAL", command=lambda: webbrowser.open_new_tab("https://www.virustotal.com/"))
|
||
|
||
help = tk.Menu(menu, tearoff=0, background="white") # 设置“帮助”菜单栏
|
||
|
||
menu.add_cascade(label="帮助", menu=help)
|
||
help.add_command(label="程序官网", command=OpenProgramURL) # 设置“程序官网”项
|
||
help.add_separator()
|
||
help.add_command(label="小提示", command=helps) # 设置“小提示”项
|
||
help.add_command(label="更新内容", command=UpdateThings) # 设置“更新内容”项
|
||
help.add_command(label="谢明名单", command=ThankWindow)
|
||
help.add_separator()
|
||
help.add_command(label="更新这个程序", command=UpdateWindow.ShowWindow)
|
||
help.add_command(label="反馈这个程序的建议和问题", command=WineRunnerBugUpload)
|
||
help.add_command(label="关于这个程序", command=about_this_program) # 设置“关于这个程序”项
|
||
help.add_separator()
|
||
moreProgram = tk.Menu(menu, tearoff=0, background="white")
|
||
help.add_cascade(label="更多生态适配应用", menu=moreProgram)
|
||
moreProgram.add_command(label="运行 Android 应用:UEngine 运行器", command=lambda: webbrowser.open_new_tab("https://gitee.com/gfdgd-xi/uengine-runner"))
|
||
# 设置窗口
|
||
win.iconphoto(False, tk.PhotoImage(file=iconPath))
|
||
#win.config(bg="white")
|
||
win.config(menu=menu)
|
||
# 设置控件
|
||
e1.set(setting["DefultBotton"])
|
||
if len(sys.argv) > 1 and sys.argv[1]:
|
||
e2.set(sys.argv[1])
|
||
menu.configure(activebackground="dodgerblue")
|
||
programmenu.configure(activebackground="dodgerblue")
|
||
wineOption.configure(activebackground="dodgerblue")
|
||
wineDefultMenu.configure(activebackground="dodgerblue")
|
||
wineInstall.configure(activebackground="dodgerblue")
|
||
opengl.configure(activebackground="dodgerblue")
|
||
winbind.configure(activebackground="dodgerblue")
|
||
virtualMachine.configure(activebackground="dodgerblue")
|
||
safeWebsize.configure(activebackground="dodgerblue")
|
||
moreProgram.configure(activebackground="dodgerblue")
|
||
help.configure(activebackground="dodgerblue")
|
||
e1['value'] = findExeHistory
|
||
e2['value'] = wineBottonHistory
|
||
combobox1['value'] = shellHistory
|
||
returnText.insert("end", "此可以查看到 Wine 应用安装时的程序返回值")
|
||
returnText.config(state=tk.DISABLED)
|
||
if not os.path.exists("/opt/durapps/spark-dwine-helper/spark-dwine-helper-settings/settings.sh"):
|
||
sparkWineSetting.config(state=tk.DISABLED)
|
||
# 启动窗口
|
||
if setting["CenterWindow"]:
|
||
try:
|
||
# 窗口居中(如果设置开启)
|
||
win.update()
|
||
# 获取主显示器分辨率
|
||
for i in GetScreenSize():
|
||
if i[4]:
|
||
win.geometry(f"{win.winfo_width()}x{win.winfo_height()}+{i[2] + (i[0] // 2 - win.winfo_width() // 2)}+{i[3] + (i[1] // 2 - win.winfo_height() // 2)}")
|
||
except:
|
||
print("设置居中错误,忽略")
|
||
# 显示窗口
|
||
win.mainloop() |