From 1c83689a6b17f58208020d40215fccba0ca85049 Mon Sep 17 00:00:00 2001 From: gfdgd xi <3025613752@qq.com> Date: Sun, 30 May 2021 13:27:17 +0800 Subject: [PATCH] 1.1.0 --- build/DEBIAN/postinst | 1 + build/opt/apps/uengine-runner/uengine-runner | 132 ++++++++++++++----- build/usr/bin/uengine-runner | 132 ++++++++++++++----- spark-uengine-runner.deb | Bin 15380 -> 16144 bytes 4 files changed, 199 insertions(+), 66 deletions(-) diff --git a/build/DEBIAN/postinst b/build/DEBIAN/postinst index 57c9407..658f2be 100755 --- a/build/DEBIAN/postinst +++ b/build/DEBIAN/postinst @@ -2,3 +2,4 @@ sudo pip3 install --upgrade pip sudo pip3 install --upgrade virtualenv pip3 install pillow +pip3 install ttkthemes \ No newline at end of file diff --git a/build/opt/apps/uengine-runner/uengine-runner b/build/opt/apps/uengine-runner/uengine-runner index ed3a53b..2b2eb38 100755 --- a/build/opt/apps/uengine-runner/uengine-runner +++ b/build/opt/apps/uengine-runner/uengine-runner @@ -2,9 +2,9 @@ # 使用系统默认的 python3 运行 ########################################################################################### # 作者:gfdgd xi -# 版本:1.0.0 -# 更新时间:2021年 -# 感谢: +# 版本:1.1.0 +# 更新时间:2021年5月30日 +# 感谢:anbox 和 统信 # 基于 Python3 的 tkinter 构建 ########################################################################################### ################# @@ -19,8 +19,10 @@ import traceback import threading import webbrowser import subprocess +import ttkthemes import tkinter as tk import tkinter.ttk as ttk +import tkinter.tix as tix import tkinter.messagebox as messagebox import tkinter.filedialog as filedialog import PIL.Image as Image @@ -30,20 +32,28 @@ def KillAdbProgress(): DisabledAndEnbled(True) Return = GetCommandReturn("killall adb") if Return is "": - Return = "OK!" + Return = "进程已经杀死!" messagebox.showinfo(title="tips", message=Return) DisabledAndEnbled(False) def Button1Click(): if combobox2.get() is "": - messagebox.showerror(title="Tips", message="Don't input right things in ComboBox") + messagebox.showerror(title="提示", message="信息没有填写完整,无法继续连接 IP") return DisabledAndEnbled(True) threading.Thread(target=ConnectPhoneIp).start() def ConnectPhoneIp(): global phoneIp - messagebox.showinfo(title="tips", message=GetCommandReturn("adb connect '{}'".format(combobox2.get()))) + messagebox.showinfo(title="提示", message=GetCommandReturn("adb connect '{}'".format(combobox2.get()))) + phoneIp.append(combobox2.get()) + combobox2['value'] = phoneIp + write_txt(get_home() + "/.config/uengine-runner/PhoneIp.json", str(json.dumps(ListToDictionary(phoneIp)))) # 将历史记录的数组转换为字典并写入 + DisabledAndEnbled(False) + +def ConnectPhoneIpDefult(): + global phoneIp + messagebox.showinfo(title="提示", message=GetCommandReturn("adb connect '192.168.250.2'")) phoneIp.append(combobox2.get()) combobox2['value'] = phoneIp write_txt(get_home() + "/.config/uengine-runner/PhoneIp.json", str(json.dumps(ListToDictionary(phoneIp)))) # 将历史记录的数组转换为字典并写入 @@ -51,20 +61,36 @@ def ConnectPhoneIp(): def FindApk(): path = filedialog.askopenfilename(title="选择 Apk", filetypes=[("APK 文件", "*.apk"), ("所有文件", "*.*")], initialdir=json.loads(readtxt(get_home() + "/.config/uengine-runner/FindApk.json"))["path"]) - if not path is "": - combobox1.set(path) - write_txt(get_home() + "/.config/uengine-runner/FindApk.json", json.dumps({"path": os.path.dirname(path)})) # 写入配置文件 + if path != "" and path != "()": + try: + combobox1.set(path) + write_txt(get_home() + "/.config/uengine-runner/FindApk.json", json.dumps({"path": os.path.dirname(path)})) # 写入配置文件 + except: + pass def Button3Install(): if combobox1.get() is "": - messagebox.showerror(title="Tips", message="Don't input right things in ComboBox") + messagebox.showerror(title="提示", message="信息没有填写完整,无法继续安装 APK") return DisabledAndEnbled(True) threading.Thread(target=InstallApk, args=(combobox1.get(),)).start() +def AdbRun(): + Return = GetCommandReturn("adb devices").replace("\n", "").replace("List of devices attached", "").replace("* daemon not running; starting now at tcp:5037", "").replace("* daemon started successfully", "") + if Return is "": + return False + return True + +def AdbConnect(): + return GetCommandReturn("adb devices") + def InstallApk(path): global findApkHistory - messagebox.showinfo(title="Tips", message=GetCommandReturn("adb install '{}'".format(path))) + if not AdbRun(): + messagebox.showinfo(title="提示", message="你没有使用 adb 连接任何设备") + DisabledAndEnbled(False) + return + messagebox.showinfo(title="提示", message=GetCommandReturn("adb install '{}'".format(path))) findApkHistory.append(combobox1.get()) combobox1['value'] = findApkHistory write_txt(get_home() + "/.config/uengine-runner/FindApkHistory.json", str(json.dumps(ListToDictionary(findApkHistory)))) # 将历史记录的数组转换为字典并写入 @@ -80,6 +106,7 @@ def DisabledAndEnbled(choose): button3.configure(state=a) button4.configure(state=a) button5.configure(state=a) + button6.configure(state=a) # 需引入 subprocess def GetCommandReturn(cmd): @@ -92,22 +119,28 @@ def Button5Click(): def OpenUengineProgramList(): os.system("/usr/bin/uengine-launch.sh --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity") +def ShowAdbConnect(): + messagebox.showinfo(title="提示", message=AdbConnect()) + # 显示“关于这个程序”窗口 def about_this_program(): global about global title global iconPath - message = tk.Toplevel() - message.title("关于 {}".format(title)) - message.iconphoto(False, tk.PhotoImage(file=iconPath)) + mess = tk.Toplevel() + message = ttk.Frame(mess) + mess.resizable(0, 0) + mess.title("关于 {}".format(title)) + mess.iconphoto(False, tk.PhotoImage(file=iconPath)) img = ImageTk.PhotoImage(Image.open(iconPath)) label1 = ttk.Label(message, image=img) label2 = ttk.Label(message, text=about) - button1 = ttk.Button(message, text="确定", command=message.withdraw) + button1 = ttk.Button(message, text="确定", command=mess.withdraw) label1.pack() label2.pack() button1.pack(side="bottom") - message.mainloop() + message.pack() + mess.mainloop() # 显示“提示”窗口 def helps(): @@ -147,6 +180,7 @@ def SendUengineAndroidListForDesktop(): try: if os.path.exists("{}/{}".format(get_desktop_path(), desktopName)): if not messagebox.askokcancel(title="提示", message="桌面已经存在快捷方式,你确定要覆盖吗?"): + DisabledAndEnbled(False) return shutil.copy(desktop, get_desktop_path()) messagebox.showinfo(title="提示", message="发送成功!") @@ -175,6 +209,7 @@ def SendUengineAndroidListForLauncher(): try: if os.path.exists("{}/.local/share/applications/{}".format(get_home(), desktopName)): if not messagebox.askokcancel(title="提示", message="启动器已经存在快捷方式,你确定要覆盖吗?"): + DisabledAndEnbled(False) return if not os.path.exists("{}/.local/share/applications/".format(get_home())): os.makedirs("{}/.local/share/applications/".format(get_home())) @@ -206,11 +241,16 @@ def write_txt(path, things): file.write(things) # 写入文本 file.close() # 关闭文本对象 +def ShowUseProgram(): + global title + global useProgram + messagebox.showinfo(title="{} 使用的程序列表(部分)".format(title), message=useProgram) + ########################### # 程序信息 ########################### programUrl = "https://gitee.com/gfdgd-xi/uengine-runner" -version = "1.0.0" +version = "1.1.0" goodRunSystem = "Linux" about = '''一个基于 Python3 的 tkinter 制作的 uengine APK 安装器 版本:{} @@ -219,14 +259,23 @@ tkinter 版本:{} 程序官网:{} ©2021-{} gfdgd xi'''.format(version, goodRunSystem, tk.TkVersion, programUrl, time.strftime("%Y")) tips = '''提示: -1、None''' -updateThingsString = '''''' +1、先连接设备再安装应用 +2、支持连接其他 Android 系统操作(需要进行设置)''' +updateThingsString = '''1、修改了因编写时出现的中、英文混用的情况 +2、支持一键连接默认 IP +3、修复在不连接设备直接选择 apk 安装时会卡住的问题 +4、修复在把“uengine 程序菜单”发送到桌面或启动器如果询问覆盖时点击取消会卡住的问题 +5、修改了程序界面为白色调,不和标题栏冲突矛盾''' title = "uengine 运行器 {}".format(version) -updateTime = "2021年" +updateTime = "2021年5月30日" updateThings = "{} 更新内容:\n{}\n更新时间:{}".format(version, updateThingsString, updateTime, time.strftime("%Y")) iconPath = "/opt/apps/uengine-runner/icon.png" desktop = "/opt/apps/uengine-runner/UengineAndroidProgramList.desktop" desktopName = "UengineAndroidProgramList.desktop" +useProgram = '''1、uengine(anbox) +2、Python3 +3、tkinter(tkinter.tk、ttkthemes 和 tkinter.ttk) +……''' ########################### # 加载配置 @@ -249,9 +298,14 @@ phoneIp = list(json.loads(readtxt(get_home() + "/.config/uengine-runner/PhoneIp. ########################### # 窗口创建 ########################### -window = tk.Tk() -window.title(title) -window.iconphoto(False, tk.PhotoImage(file=iconPath)) +win = tk.Tk() +style = ttkthemes.ThemedStyle(win) +style.set_theme("adapta") +window = ttk.Frame(win) +win.attributes('-alpha', 0.5) +win.title(title) +win.resizable(0, 0) +win.iconphoto(False, tk.PhotoImage(file=iconPath)) frame1 = ttk.Frame(window) frame2 = ttk.Frame(window) label1 = ttk.Label(window, text="要安装的 apk 路径:") @@ -261,30 +315,40 @@ combobox2 = ttk.Combobox(window, width=100) button1 = ttk.Button(frame1, text="连接设备", command=ConnectPhoneIp) button2 = ttk.Button(window, text="浏览", command=FindApk) button3 = ttk.Button(frame2, text="安装", command=Button3Install) -button4 = ttk.Button(frame1, text="Kill Adb Progress", command=KillAdbProgress) -button5 = ttk.Button(frame2, text="Open uengine Program List", command=Button5Click) -menu = tk.Menu(window) # 设置菜单栏 -programmenu = tk.Menu(menu, tearoff=0) # 设置“程序”菜单栏 +button4 = ttk.Button(frame1, text="关闭 adb 软件进程", command=KillAdbProgress) +button5 = ttk.Button(frame2, text="打开 uengine 应用列表", command=Button5Click) +button6 = ttk.Button(frame1, text="连接默认 IP", command=ConnectPhoneIpDefult) +menu = tk.Menu(window, background="white") # 设置菜单栏 +programmenu = tk.Menu(menu, tearoff=0, background="white") # 设置“程序”菜单栏 +adb = tk.Menu(menu, tearoff=0, background="white") +uengine = tk.Menu(menu, tearoff=0, background="white") +help = tk.Menu(menu, tearoff=0, background="white") # 设置“帮助”菜单栏 menu.add_cascade(label="程序", menu=programmenu) +menu.add_cascade(label="adb", menu=adb) +menu.add_cascade(label="uengine", menu=uengine) +menu.add_cascade(label="帮助", menu=help) programmenu.add_command(label="清空软件历史记录", command=CleanProgramHistory) programmenu.add_separator() # 设置分界线 programmenu.add_command(label="退出程序", command=window.quit) # 设置“退出程序”项 -uengine = tk.Menu(menu, tearoff=0) -menu.add_cascade(label="uengine", menu=uengine) +adb.add_command(label="adb 连接的设备", command=ShowAdbConnect) uengine.add_command(label="发送 uengine 应用列表到桌面", command=SendUengineAndroidListForDesktop) uengine.add_command(label="发送 uengine 应用列表到启动器", command=SendUengineAndroidListForLauncher) -help = tk.Menu(menu, tearoff=0) # 设置“帮助”菜单栏 -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=ShowUseProgram) # 设置“更新内容”项 help.add_command(label="关于这个程序", command=about_this_program) # 设置“关于这个程序”项 +menu.configure(activebackground="white") +help.configure(activebackground="white") +uengine.configure(activebackground="white") +adb.configure(activebackground="white") +programmenu.configure(activebackground="white") # 设置控件 combobox2['value'] = phoneIp combobox1['value'] = findApkHistory # -window.config(menu=menu) # 显示菜单栏 +win.config(menu=menu) # 显示菜单栏 label1.grid(row=2, column=0) label2.grid(row=0, column=0) combobox1.grid(row=2, column=1) @@ -294,6 +358,8 @@ button2.grid(row=2, column=2) button3.grid(row=0, column=0) button4.grid(column=1, row=0) button5.grid(row=0, column=1) +button6.grid(row=0, column=3) frame1.grid(row=1, columnspa=3) frame2.grid(row=3, columnspa=3) -window.mainloop() \ No newline at end of file +window.pack() +win.mainloop() \ No newline at end of file diff --git a/build/usr/bin/uengine-runner b/build/usr/bin/uengine-runner index ed3a53b..2b2eb38 100755 --- a/build/usr/bin/uengine-runner +++ b/build/usr/bin/uengine-runner @@ -2,9 +2,9 @@ # 使用系统默认的 python3 运行 ########################################################################################### # 作者:gfdgd xi -# 版本:1.0.0 -# 更新时间:2021年 -# 感谢: +# 版本:1.1.0 +# 更新时间:2021年5月30日 +# 感谢:anbox 和 统信 # 基于 Python3 的 tkinter 构建 ########################################################################################### ################# @@ -19,8 +19,10 @@ import traceback import threading import webbrowser import subprocess +import ttkthemes import tkinter as tk import tkinter.ttk as ttk +import tkinter.tix as tix import tkinter.messagebox as messagebox import tkinter.filedialog as filedialog import PIL.Image as Image @@ -30,20 +32,28 @@ def KillAdbProgress(): DisabledAndEnbled(True) Return = GetCommandReturn("killall adb") if Return is "": - Return = "OK!" + Return = "进程已经杀死!" messagebox.showinfo(title="tips", message=Return) DisabledAndEnbled(False) def Button1Click(): if combobox2.get() is "": - messagebox.showerror(title="Tips", message="Don't input right things in ComboBox") + messagebox.showerror(title="提示", message="信息没有填写完整,无法继续连接 IP") return DisabledAndEnbled(True) threading.Thread(target=ConnectPhoneIp).start() def ConnectPhoneIp(): global phoneIp - messagebox.showinfo(title="tips", message=GetCommandReturn("adb connect '{}'".format(combobox2.get()))) + messagebox.showinfo(title="提示", message=GetCommandReturn("adb connect '{}'".format(combobox2.get()))) + phoneIp.append(combobox2.get()) + combobox2['value'] = phoneIp + write_txt(get_home() + "/.config/uengine-runner/PhoneIp.json", str(json.dumps(ListToDictionary(phoneIp)))) # 将历史记录的数组转换为字典并写入 + DisabledAndEnbled(False) + +def ConnectPhoneIpDefult(): + global phoneIp + messagebox.showinfo(title="提示", message=GetCommandReturn("adb connect '192.168.250.2'")) phoneIp.append(combobox2.get()) combobox2['value'] = phoneIp write_txt(get_home() + "/.config/uengine-runner/PhoneIp.json", str(json.dumps(ListToDictionary(phoneIp)))) # 将历史记录的数组转换为字典并写入 @@ -51,20 +61,36 @@ def ConnectPhoneIp(): def FindApk(): path = filedialog.askopenfilename(title="选择 Apk", filetypes=[("APK 文件", "*.apk"), ("所有文件", "*.*")], initialdir=json.loads(readtxt(get_home() + "/.config/uengine-runner/FindApk.json"))["path"]) - if not path is "": - combobox1.set(path) - write_txt(get_home() + "/.config/uengine-runner/FindApk.json", json.dumps({"path": os.path.dirname(path)})) # 写入配置文件 + if path != "" and path != "()": + try: + combobox1.set(path) + write_txt(get_home() + "/.config/uengine-runner/FindApk.json", json.dumps({"path": os.path.dirname(path)})) # 写入配置文件 + except: + pass def Button3Install(): if combobox1.get() is "": - messagebox.showerror(title="Tips", message="Don't input right things in ComboBox") + messagebox.showerror(title="提示", message="信息没有填写完整,无法继续安装 APK") return DisabledAndEnbled(True) threading.Thread(target=InstallApk, args=(combobox1.get(),)).start() +def AdbRun(): + Return = GetCommandReturn("adb devices").replace("\n", "").replace("List of devices attached", "").replace("* daemon not running; starting now at tcp:5037", "").replace("* daemon started successfully", "") + if Return is "": + return False + return True + +def AdbConnect(): + return GetCommandReturn("adb devices") + def InstallApk(path): global findApkHistory - messagebox.showinfo(title="Tips", message=GetCommandReturn("adb install '{}'".format(path))) + if not AdbRun(): + messagebox.showinfo(title="提示", message="你没有使用 adb 连接任何设备") + DisabledAndEnbled(False) + return + messagebox.showinfo(title="提示", message=GetCommandReturn("adb install '{}'".format(path))) findApkHistory.append(combobox1.get()) combobox1['value'] = findApkHistory write_txt(get_home() + "/.config/uengine-runner/FindApkHistory.json", str(json.dumps(ListToDictionary(findApkHistory)))) # 将历史记录的数组转换为字典并写入 @@ -80,6 +106,7 @@ def DisabledAndEnbled(choose): button3.configure(state=a) button4.configure(state=a) button5.configure(state=a) + button6.configure(state=a) # 需引入 subprocess def GetCommandReturn(cmd): @@ -92,22 +119,28 @@ def Button5Click(): def OpenUengineProgramList(): os.system("/usr/bin/uengine-launch.sh --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity") +def ShowAdbConnect(): + messagebox.showinfo(title="提示", message=AdbConnect()) + # 显示“关于这个程序”窗口 def about_this_program(): global about global title global iconPath - message = tk.Toplevel() - message.title("关于 {}".format(title)) - message.iconphoto(False, tk.PhotoImage(file=iconPath)) + mess = tk.Toplevel() + message = ttk.Frame(mess) + mess.resizable(0, 0) + mess.title("关于 {}".format(title)) + mess.iconphoto(False, tk.PhotoImage(file=iconPath)) img = ImageTk.PhotoImage(Image.open(iconPath)) label1 = ttk.Label(message, image=img) label2 = ttk.Label(message, text=about) - button1 = ttk.Button(message, text="确定", command=message.withdraw) + button1 = ttk.Button(message, text="确定", command=mess.withdraw) label1.pack() label2.pack() button1.pack(side="bottom") - message.mainloop() + message.pack() + mess.mainloop() # 显示“提示”窗口 def helps(): @@ -147,6 +180,7 @@ def SendUengineAndroidListForDesktop(): try: if os.path.exists("{}/{}".format(get_desktop_path(), desktopName)): if not messagebox.askokcancel(title="提示", message="桌面已经存在快捷方式,你确定要覆盖吗?"): + DisabledAndEnbled(False) return shutil.copy(desktop, get_desktop_path()) messagebox.showinfo(title="提示", message="发送成功!") @@ -175,6 +209,7 @@ def SendUengineAndroidListForLauncher(): try: if os.path.exists("{}/.local/share/applications/{}".format(get_home(), desktopName)): if not messagebox.askokcancel(title="提示", message="启动器已经存在快捷方式,你确定要覆盖吗?"): + DisabledAndEnbled(False) return if not os.path.exists("{}/.local/share/applications/".format(get_home())): os.makedirs("{}/.local/share/applications/".format(get_home())) @@ -206,11 +241,16 @@ def write_txt(path, things): file.write(things) # 写入文本 file.close() # 关闭文本对象 +def ShowUseProgram(): + global title + global useProgram + messagebox.showinfo(title="{} 使用的程序列表(部分)".format(title), message=useProgram) + ########################### # 程序信息 ########################### programUrl = "https://gitee.com/gfdgd-xi/uengine-runner" -version = "1.0.0" +version = "1.1.0" goodRunSystem = "Linux" about = '''一个基于 Python3 的 tkinter 制作的 uengine APK 安装器 版本:{} @@ -219,14 +259,23 @@ tkinter 版本:{} 程序官网:{} ©2021-{} gfdgd xi'''.format(version, goodRunSystem, tk.TkVersion, programUrl, time.strftime("%Y")) tips = '''提示: -1、None''' -updateThingsString = '''''' +1、先连接设备再安装应用 +2、支持连接其他 Android 系统操作(需要进行设置)''' +updateThingsString = '''1、修改了因编写时出现的中、英文混用的情况 +2、支持一键连接默认 IP +3、修复在不连接设备直接选择 apk 安装时会卡住的问题 +4、修复在把“uengine 程序菜单”发送到桌面或启动器如果询问覆盖时点击取消会卡住的问题 +5、修改了程序界面为白色调,不和标题栏冲突矛盾''' title = "uengine 运行器 {}".format(version) -updateTime = "2021年" +updateTime = "2021年5月30日" updateThings = "{} 更新内容:\n{}\n更新时间:{}".format(version, updateThingsString, updateTime, time.strftime("%Y")) iconPath = "/opt/apps/uengine-runner/icon.png" desktop = "/opt/apps/uengine-runner/UengineAndroidProgramList.desktop" desktopName = "UengineAndroidProgramList.desktop" +useProgram = '''1、uengine(anbox) +2、Python3 +3、tkinter(tkinter.tk、ttkthemes 和 tkinter.ttk) +……''' ########################### # 加载配置 @@ -249,9 +298,14 @@ phoneIp = list(json.loads(readtxt(get_home() + "/.config/uengine-runner/PhoneIp. ########################### # 窗口创建 ########################### -window = tk.Tk() -window.title(title) -window.iconphoto(False, tk.PhotoImage(file=iconPath)) +win = tk.Tk() +style = ttkthemes.ThemedStyle(win) +style.set_theme("adapta") +window = ttk.Frame(win) +win.attributes('-alpha', 0.5) +win.title(title) +win.resizable(0, 0) +win.iconphoto(False, tk.PhotoImage(file=iconPath)) frame1 = ttk.Frame(window) frame2 = ttk.Frame(window) label1 = ttk.Label(window, text="要安装的 apk 路径:") @@ -261,30 +315,40 @@ combobox2 = ttk.Combobox(window, width=100) button1 = ttk.Button(frame1, text="连接设备", command=ConnectPhoneIp) button2 = ttk.Button(window, text="浏览", command=FindApk) button3 = ttk.Button(frame2, text="安装", command=Button3Install) -button4 = ttk.Button(frame1, text="Kill Adb Progress", command=KillAdbProgress) -button5 = ttk.Button(frame2, text="Open uengine Program List", command=Button5Click) -menu = tk.Menu(window) # 设置菜单栏 -programmenu = tk.Menu(menu, tearoff=0) # 设置“程序”菜单栏 +button4 = ttk.Button(frame1, text="关闭 adb 软件进程", command=KillAdbProgress) +button5 = ttk.Button(frame2, text="打开 uengine 应用列表", command=Button5Click) +button6 = ttk.Button(frame1, text="连接默认 IP", command=ConnectPhoneIpDefult) +menu = tk.Menu(window, background="white") # 设置菜单栏 +programmenu = tk.Menu(menu, tearoff=0, background="white") # 设置“程序”菜单栏 +adb = tk.Menu(menu, tearoff=0, background="white") +uengine = tk.Menu(menu, tearoff=0, background="white") +help = tk.Menu(menu, tearoff=0, background="white") # 设置“帮助”菜单栏 menu.add_cascade(label="程序", menu=programmenu) +menu.add_cascade(label="adb", menu=adb) +menu.add_cascade(label="uengine", menu=uengine) +menu.add_cascade(label="帮助", menu=help) programmenu.add_command(label="清空软件历史记录", command=CleanProgramHistory) programmenu.add_separator() # 设置分界线 programmenu.add_command(label="退出程序", command=window.quit) # 设置“退出程序”项 -uengine = tk.Menu(menu, tearoff=0) -menu.add_cascade(label="uengine", menu=uengine) +adb.add_command(label="adb 连接的设备", command=ShowAdbConnect) uengine.add_command(label="发送 uengine 应用列表到桌面", command=SendUengineAndroidListForDesktop) uengine.add_command(label="发送 uengine 应用列表到启动器", command=SendUengineAndroidListForLauncher) -help = tk.Menu(menu, tearoff=0) # 设置“帮助”菜单栏 -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=ShowUseProgram) # 设置“更新内容”项 help.add_command(label="关于这个程序", command=about_this_program) # 设置“关于这个程序”项 +menu.configure(activebackground="white") +help.configure(activebackground="white") +uengine.configure(activebackground="white") +adb.configure(activebackground="white") +programmenu.configure(activebackground="white") # 设置控件 combobox2['value'] = phoneIp combobox1['value'] = findApkHistory # -window.config(menu=menu) # 显示菜单栏 +win.config(menu=menu) # 显示菜单栏 label1.grid(row=2, column=0) label2.grid(row=0, column=0) combobox1.grid(row=2, column=1) @@ -294,6 +358,8 @@ button2.grid(row=2, column=2) button3.grid(row=0, column=0) button4.grid(column=1, row=0) button5.grid(row=0, column=1) +button6.grid(row=0, column=3) frame1.grid(row=1, columnspa=3) frame2.grid(row=3, columnspa=3) -window.mainloop() \ No newline at end of file +window.pack() +win.mainloop() \ No newline at end of file diff --git a/spark-uengine-runner.deb b/spark-uengine-runner.deb index fb1e76cf129bb2e769d0224e591b3d58f06d7e0b..622f719cb2172cb0d61d65ef143a2e763c2700e8 100644 GIT binary patch delta 15734 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⪪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 Z>Hp~!1MN#j?{{RmTqgem| delta 14997 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 B92x)s