我想创建一个像开/关切换一样的 GUI 小部件来运行一组命令。
例如,使用 打开或关闭 wifi 热点ap-hotspot start/stop
。
谁能帮帮我……
答案1
你可以练习一个通用的方法为设置、连接等创建切换脚本/功能。此外,您可能能够在不同情况下重复使用大部分代码。然而,一个简单的“一体化”解决方案,适用于不同的情况,并且无需任何编码知识或感觉很难给出。你依赖于脚本必须在其间切换的两种状态的性质、它们对应的命令以及你可以使用(或不使用)的方法来检查当前状态。
话虽如此,鉴于您的切换热点示例,下面是三个现成的设置版本,从相对简单到稍微复杂一些。前两个是最“通用”的;第三个仅适用于 Unity。
切换脚本的一般“结构”如下:
> check what is the current_status
> if current_status = A:
(switch icon to icon_b)
run command to change state to B
(check if toggle command was successful, if not > switch icon back)
> else:
(switch launcher icon to icon_a)
run command to change to change to A
(check if toggle command was successful, if not > switch icon back)
切换设置;三个例子
- 使用桌面上的单个启动器(桌面文件)进行切换。
- 同上,但也有切换图标,以显示当前状态
- 通过 Unity 启动器中的图标进行切换,切换图标可显示当前状态
笔记:
- 由于系统会要求您输入密码,因此您需要安装 gksu(如果您的系统上尚未安装)。示例 3 不应在 12.04 或更早版本上使用(原样)。
- 请记住,请求管理员权限的脚本存在潜在的安全风险。如果您不确定谁在您的计算机上做了什么,请将其存储在安全目录中。
1. 使用桌面上的单个启动器(桌面文件)进行切换
最简单的方法:通过桌面上的(固定)启动器切换
指示:
图标:
从下面下载任一图标(右键单击 > 安全为),并将其安全保存toggle_icon.png
在您选择的位置。
剧本:
复制下面的文本,将其粘贴到一个空文件中,然后在您选择的位置将其保存为 hotspot.py。
#!/usr/bin/python3
import subprocess
# identifying string to look for when "pstree" is run
running_id = "ap-hotspot"
def check_ifrunning():
# check if hotspot is up or down
get_pstreeinfo = subprocess.Popen(["pstree"], stdout=subprocess.PIPE)
output = (get_pstreeinfo.communicate()[0].decode("utf-8"))
if running_id in output:
return "running"
else:
return "not_running"
def toggle_connection():
runcheck = check_ifrunning()
if runcheck == "not_running":
# command to start hotspot (spaces replaced by ",")
subprocess.Popen(["gksu", "ap-hotspot", "start"])
else:
# idem, stop hotspot
subprocess.Popen(["gksu", "ap-hotspot", "stop"])
toggle_connection()
创建桌面文件:
复制下面的文本,将其粘贴到一个空的文本文件中。在行中添加脚本的正确路径Exec=
,在行中添加正确的路径Icon=
,并将其保存到您的桌面hotspot_toggle.desktop
。使其可执行,您的设置应该可以正常工作。
[Desktop Entry]
Name=Hotspot toggle
Comment=Hotspot toggle
Categories=Accessories
Exec=python3 /path/to/script/hotspot.py
Icon=/path/to/icon/toggle_icon.png
Terminal=false
Type=Application
StartupNotify=true
2. 使用桌面上的单个启动器(桌面文件)进行切换,并具有图标更改效果
这是第一个例子的增强版本:图标将在您的桌面上变为toggle_officon.png
/ toggle_onicon.png
,取决于热点是打开还是关闭。
指示:
图标:
下载两个都第一个示例中的图标,将它们安全保存为
toggle_officon.png (the grey one)
toggle_onicon.png (the green one)
在您选择的位置。
剧本:
复制下面的文本,将其粘贴到一个空文件中,并将其保存为 hotspot.py,保存在您选择的位置。将正确的路径添加到以path_todtfile =
(桌面文件路径,请参阅下文)、 icon_offpath =
(toggle_officon.png 路径) 和icon_onpath =
(toggle_onicon.png 路径) 开头的行中。注意:桌面文件的“真实”名称是您保存时命名的名称。名称你看在您的界面中是在Name=
桌面文件的行中定义的。
#!/usr/bin/python3
import subprocess
import time
wait = 10
# identifying difference on pstree command on / off
running_id = "ap-hotspot"
# pathto_desktop file
path_todtfile = "/path/to/desktop_file/toggle.desktop"
# paths to icons
icon_offpath = "/path/to/toggle_off_icon/toggle_officon.png"
icon_onpath = "/path/to/toggle_on_icon/toggle_onicon.png"
def set_icon(set_mode, state):
if state == "running":
iconset = [icon_onpath, icon_offpath]
else:
iconset = [icon_offpath, icon_onpath]
if set_mode == "set_current":
appropriate_iconpath = iconset[0]
else:
appropriate_iconpath = iconset[1]
with open(path_todtfile, "r") as editicon:
editicon = editicon.readlines()
line_toedit = [editicon.index(line) for line in editicon if\
line.startswith("Icon=")][0]
if not editicon[line_toedit] == "Icon="+appropriate_iconpath+"\n":
editicon[line_toedit] = "Icon="+appropriate_iconpath+"\n"
with open(path_todtfile, "wt") as edited_icon:
for line in editicon:
edited_icon.write(line)
else:
pass
def check_ifrunning():
# check if hotspot is up or down
get_pstreeinfo = subprocess.Popen(["pstree"], stdout=subprocess.PIPE)
output = (get_pstreeinfo.communicate()[0].decode("utf-8"))
if running_id in output:
return "running"
else:
return "not_running"
def toggle_connection():
runcheck = check_ifrunning()
set_icon("set_alter", runcheck)
if runcheck == "not_running":
subprocess.call(["gksu", "ap-hotspot", "start"])
else:
subprocess.call(["gksu", "ap-hotspot", "stop"])
time.sleep(wait)
runcheck = check_ifrunning()
set_icon("set_current", runcheck)
toggle_connection()
桌面文件:
像示例 1 中那样创建桌面文件。在行中添加脚本的正确路径Exec=
,在中添加两个图标之一的路径Icon=
(第一次使用时会理顺),并将其作为安全保存到桌面toggle.desktop
。使其可执行,您的设置应该可以正常工作。
3. 从 Unity 启动器中的图标切换,切换图标以显示当前状态
停机 / 运行
(该示例不应在 12.04 或更早版本中使用。)
图标:
下载两个都第一个示例中的图标,将它们安全保存为
toggle_officon.png (the grey one)
toggle_onicon.png (the green one)
在您选择的位置。
剧本:
复制下面的文本。将其粘贴到一个空文件中,然后在适合您的位置将其保存为 hotspot.py。
#!/usr/bin/python3
import subprocess
import getpass
import time
# time to wait, to check if hotspot was established (set correct icon)
wait = 10
# identifying difference on pstree command
running_id = "ap-hotspot"
# location of the launcher restore script
backup_copy = "/home/"+getpass.getuser()+"/.restore_currentlauncher.sh"
# name of the desktop file if hotspot is down
mention_ifdown = 'application://hotspot_off.desktop'
# name of the desktop file if hotspot is running
mention_ifup = 'application://hotspot_on.desktop'
def check_ifrunning():
# check if hotspot is up or down
get_pstreeinfo = subprocess.Popen(["pstree"], stdout=subprocess.PIPE)
output = (get_pstreeinfo.communicate()[0].decode("utf-8"))
if running_id in output:
return "running"
else:
return "not_running"
def read_currentlauncher():
# read the current launcher contents
get_launcheritems = subprocess.Popen([
"gsettings", "get", "com.canonical.Unity.Launcher", "favorites"
], stdout=subprocess.PIPE)
return eval((get_launcheritems.communicate()[0].decode("utf-8")))
def set_current_launcher(current_launcher):
# before editing the launcher, create restore script
backup_data = read_currentlauncher()
with open(backup_copy, "wt") as create_backup:
create_backup.write(
"#!/bin/sh\n\n"\
"gsettings set com.canonical.Unity.Launcher favorites "+\
'"'+str(backup_data)+'"'
)
# preparing subprocess command string
current_launcher = str(current_launcher).replace(", ", ",")
subprocess.Popen([
"gsettings", "set", "com.canonical.Unity.Launcher", "favorites",
current_launcher,
])
def set_icon(change_mode):
# defines the appropriate icon in the launcher
state = check_ifrunning()
if state == "running":
if change_mode == "set_current":
iconset = [mention_ifup, mention_ifdown]
else:
iconset = [mention_ifdown, mention_ifup]
elif state == "not_running":
if change_mode == "set_current":
iconset = [mention_ifdown, mention_ifup]
else:
iconset = [mention_ifup, mention_ifdown]
# set the defined icon
current_launcher = read_currentlauncher()
if iconset[0] in current_launcher:
pass
else:
index = current_launcher.index(iconset[1])
current_launcher.pop(index)
set_current_launcher(current_launcher)
time.sleep(1)
current_launcher.insert(index, iconset[0])
set_current_launcher(current_launcher)
def toggle_connection():
set_icon("set_alter")
runcheck = check_ifrunning()
if runcheck == "not_running":
subprocess.call(["gksu", "ap-hotspot", "start"])
else:
subprocess.call(["gksu", "ap-hotspot", "stop"])
time.sleep(wait)
set_icon("set_current")
toggle_connection()
两个桌面文件将在启动器中切换:
下面是您需要的两个桌面文件。打开一个空的文本文件,粘贴下面的代码(在单独的文件中),将路径替换为您上面保存的图标的实际路径和脚本的路径,然后将它们保存为~/.local/share/applications
、hotspot_off.desktop
和hotspot_on.desktop
:
热点关闭.桌面:
[Desktop Entry]
Name=Hotspot off
Exec=python3 /path/to/script/hotspot.py
Icon=/path/to/toggle_officon/toggle_officon.png
Terminal=false
Type=Application
NoDisplay=true
桌面热点:
[Desktop Entry]
Name=Hotspot on
Exec=python3 /path/to/script/hotspot.py
Icon=/path/to/toggle_officon/toggle_onicon.png
Terminal=false
Type=Application
NoDisplay=true
最后,将其中一个桌面文件拖到启动器上。不用担心你选错了,第一次运行时它会被纠正。