添加几个功能

This commit is contained in:
liyp 2023-12-24 20:45:07 +08:00
parent a9bcd96046
commit 96518ebc5d
2 changed files with 166 additions and 14 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
.venv
main/test.py
main/test1.py

View file

@ -1,14 +1,25 @@
import sys
import platform
import requests
from PyQt5.QtWidgets import QApplication, QMainWindow, QSystemTrayIcon, QMenu, QAction,QActionGroup
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QTimer,pyqtSignal,QThread
import json
import aiohttp
import asyncio
class TrayIconExample(QMainWindow):
speed_data = pyqtSignal(dict)
def __init__(self):
super(TrayIconExample, self).__init__()
self.init_ui()
# 启动异步任务
self.worker_thread = WorkerThread(self)
self.worker_thread.data_ready.connect(self.update_speed_data)
self.worker_thread.start()
def init_ui(self):
self.setWindowTitle('Clash Tray')
@ -23,11 +34,39 @@ class TrayIconExample(QMainWindow):
exit_action = QAction('退出', self)
self.tun_mode = QAction('TUN模式', self)
self.tun_mode.setCheckable(True)
# 获取环境变量
self.copy_env=QAction('复制环境变量',self)
# 创建一个 QActionGroup
self.more_menu=QMenu('更多',self)
self.upload_speed=QAction('⬆️上传速度',self)
self.download_speed=QAction('⬇️下载速度',self)
self.upload_speed.setCheckable(False)
self.upload_speed.setEnabled(False)
self.download_speed.setCheckable(False)
self.download_speed.setEnabled(False)
# self.timer = QTimer(self)
# self.timer.timeout.connect(self.update_data)
# self.timer.start(1000) # 定时器间隔为1000毫秒1秒
# 更多 子菜单项设置
self.version=self.get_version()
self.show_version = QAction('内核版本:'+self.version, self)
self.show_version.setCheckable(False)
self.show_version.setEnabled(False)
self.restart_core=QAction('重启Clash',self)
self.more_menu.addAction(self.restart_core)
self.more_menu.addAction(self.show_version)
self.restart_core.triggered.connect(self.restart_clash)
# 创建代理模式 QActionGroup
proxy_mode_group = QActionGroup(self)
proxy_mode_group.setExclusive(True) # 设置为单选模式
# 设置代理模式菜单
self.direct_mode=QAction('直连模式',self)
self.rule_mode=QAction('规则模式',self)
self.global_mode=QAction('全局模式',self)
@ -39,12 +78,20 @@ class TrayIconExample(QMainWindow):
proxy_mode_group.addAction(self.rule_mode)
proxy_mode_group.addAction(self.global_mode)
self.tun_mode.triggered.connect(self.change_tun_mode)
exit_action.triggered.connect(self.exit_application)
# 将菜单添加到托盘图标
context_menu.addAction(self.tun_mode)
context_menu.addMenu(proxy_mode)
context_menu.addAction(exit_action)
context_menu.addAction(self.copy_env)
context_menu.addMenu(self.more_menu)
context_menu.addActions([self.upload_speed,self.download_speed,exit_action])
proxy_mode.addActions([self.direct_mode,self.rule_mode,self.global_mode])
self.copy_env.triggered.connect(self.copy_env_var)
self.direct_mode.triggered.connect(lambda:self.set_proxy_mode(0))
self.rule_mode.triggered.connect(lambda:self.set_proxy_mode(1))
self.global_mode.triggered.connect(lambda:self.set_proxy_mode(2))
@ -57,7 +104,14 @@ class TrayIconExample(QMainWindow):
tray_icon.show()
self.get_config()
self.setGeometry(100, 100, 800, 600)
self.setGeometry(200, 200, 1200, 800)
def restart_clash(self):
url,port=self.get_connect()
data={'path': '','payload': ''}
response=requests.post(url=url+':'+port+'/restart').json()
if response['status']=='ok':
print('重启成功')
def get_connect(self,url=None,port=None):
url='http://127.0.0.1'
@ -83,34 +137,130 @@ class TrayIconExample(QMainWindow):
self.tun_mode.setChecked(True)
else:
self.tun_mode.setChecked(False)
return response
def get_version(self):
url,port=self.get_connect()
response=requests.get(url=url+':'+port+'/version')
if response.status_code==200:
res=response.json()
print('version',res)
return res['version']
def set_proxy_mode(self,type):
mode=None
if type==0:
mode='direct'
# self.rule_mode.setChecked(True)
elif type==1:
mode='rule'
# self.rule_mode.setChecked(True)
elif type==2:
mode='global'
# self.global_mode.setChecked(True)
url,port=self.get_connect()
data = {"mode": mode}
response=requests.patch(url=url+':'+port+'/configs?force=true',json=data)
if response.status_code==204:
self.get_config()
def change_tun_mode(self):
url,port=self.get_connect()
print(self.tun_mode.isChecked())
data = {"tun": {"enable": False if self.tun_mode.isChecked() else True}}
print(data)
response=requests.patch(url=url+':'+port+'/configs?force=true',json=data)
if response.status_code==204:
self.get_config()
def copy_env_var(self):
sys_info=platform.uname()
clipboard = QApplication.clipboard()
env_var=''
# print(sys_info.system)
if sys_info.system == ('Linux' or 'Darwin'):
env_var='export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890'
elif sys_info.system == 'Windows':
env_var='setx https_proxy=http://127.0.0.1:7890\nsetx http_proxy=http://127.0.0.1:7890\nsetx all_proxy=socks5://127.0.0.1:7890'
# print(env_var)
clipboard.setText(env_var)
def update_speed_data(self,data):
print(data)
upload=data['up']
down=data['down']
if upload /1024<=1024 or down /1024<=1024:
upload=round(upload/1024,2)
down=round(down/1024,2)
self.upload_speed.setText('上传速度:'+str(upload)+'KB/s')
self.download_speed.setText('下载速度:'+str(down)+'KB/s')
else:
upload=round(upload/1024/1024,2)
down=round(down/1024/1024,2)
self.upload_speed.setText('上传速度:'+str(upload)+'MB/s')
self.download_speed.setText('下载速度:'+str(down)+'MB/s')
pass
def exit_application(self):
QApplication.quit()
# async def fetch_and_output_data(self):
# url = "http://127.0.0.1:9090/traffic" # 替换为实际的 API 地址
# async with aiohttp.ClientSession() as session:
# async with session.get(url, timeout=None) as response: # timeout=None 表示不设置超时
# while True:
# partial_data = await response.content.read(100) # 每次读取100字节的数据示例
# if not partial_data:
# break # 如果没有更多数据,退出循环
# # 在此处可以进行异步加载部分数据的操作,例如使用 Qt 的异步加载机制
# # print("Partial data:", partial_data)
# # 将字节数据转换为字符串
# partial_data_str = partial_data.decode('utf-8')
# print(partial_data_str)
# # 将字符串解析为 JSON 对象
# try:
# partial_data_json = json.loads(partial_data_str)
# print("Partial data:", partial_data_json)
# self.speed_data.emit(partial_data_json)
# except json.JSONDecodeError as e:
# print(f"Error decoding JSON: {e}")
# await asyncio.sleep(1) # 休眠1秒模拟每秒输出一部分数据
class WorkerThread(QThread):
data_ready = pyqtSignal(dict)
def run(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.fetch_and_output_data())
async def fetch_and_output_data(self):
url = "http://127.0.0.1:9090/traffic"
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=None) as response:
while True:
partial_data = await response.content.read(100)
if not partial_data:
break
partial_data_str = partial_data.decode('utf-8')
try:
partial_data_json = json.loads(partial_data_str)
self.data_ready.emit(partial_data_json)
except json.JSONDecodeError as e:
print(f"解析 JSON 时出错:{e}")
await asyncio.sleep(1)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = TrayIconExample()