Python PyQt、QT 浏览器调用本地exe(应用程序)及传参(Windows & Mac)
pyqt 通过浏览器打开本地app及传参(Windows & Mac)在我们使用应用时,我们经常涉及到应用通过浏览器打开本地应用,比如百度网盘、腾讯会议等等,这种浏览器打开本地app的方式,十分高大上。但你知道实现方式吗?其实,在Windows、Mac、Linux等系统中实现的方法都是「注册应用程序协议」,比如说在Windows,只需在注册表中写入应用程序启动信息,在浏览器调用程序时,会先
浏览器调用本地exe(应用程序)及传参(Windows & Mac)
文章目录
在我们使用应用时,我们经常涉及到应用通过浏览器打开本地应用,比如百度网盘、腾讯会议等等,这种浏览器打开本地app的方式,十分高大上。但你知道实现方式吗?
其实,在Windows、Mac、Linux等系统中实现的方法都是「注册应用程序协议」,比如说在Windows,只需在注册表中写入应用程序启动信息,在浏览器调用程序时,会先去注册表中查询应用信息,然后调用启动信息,即可实现协议与执行程序的关联。
一、Windows&Mac自定义URL Scheme
1、Windows 注册自定义 URL Scheme
第一步:新建 .reg 文件,内容格式如下
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\MYSCHEME]
"URL Protocol"="E:\\APP\\app.exe"
@="MYSCHEME.Protocol"
[HKEY_CLASSES_ROOT\MYSCHEME\DefaultIcon]
@="E:\\APP\\app.exe,1"
[HKEY_CLASSES_ROOT\MYSCHEME\shell]
[HKEY_CLASSES_ROOT\MYSCHEME\shell\open]
[HKEY_CLASSES_ROOT\MYSCHEME\shell\open\command]
@="\"E:\\APP\\app.exe\" --login-settings \"%1\""
上面的注册表信息,将告诉系统我们要注册一个自定义的URL Scheme,修改完成后,双击文件即可将信息写入注册表中。
- MYSCHEME: 自定义 URL Scheme 名称,此名称用于浏览器调用应用的唯一标识
- E:\APP\app.exe:APP的绝对路径
- –login-settings “%1"”: 应用启动时 传递的参数 %1为占位符
第二步:HTML文件用于浏览器启动
此时我们可以写一个HTML文件,在文件中根据自己的情况修改 a标签:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浏览器启动本地应用</title>
</head>
<body>
<a href="MYSCHEME://?token=fjasfjasndfnas">打开你的应用程序</a>
</body>
</html>
保存后,在浏览器打开此HTML文件,点击超链接,将会唤起 E:\APP\app.exe\ 并将参数–login-settings 「–login-settings=MYSCHEME://?token=fjasfjasndfnas」传递给应用程序。
此时,浏览器弹出弹窗提示用户是否启动本地应用程序,当用户选择启动后,则会将参数拼接至启动命令行中,启动程序。
E:\APP\app.exe --login-settings=“MYSCHEME://?token=fjasfjasndfnas”
2、macOS 注册自定义 URL Scheme
macOS 下与 Windows 在自定义 URL 的实现上有差异,MAC中的方法简单一些,仅需要修改 Info.plist文件即可:
Info.plist 文件位置: 应用程序名称右键 —> 显示包内容 —> contents —> Info.plist 建议使用sublime打开文件
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>MYSCHEME</string>
</array>
<key>CFBundleURLName</key>
<string>com.tencent.wemeet</string>
</dict>
</array>
其中 MYSCHEME 为自动注册到系统中的自定义 URL Scheme,当在 macOS 下通过浏览器访问 MYSCHEME:// 的地址时,浏览器将弹出弹窗提示用户是否启动本地应用程序。「注意:如果不提示的话,建议重新打包应用程序,重新生成info.plist文件」
注意:CFBundleURLName中的string为反DNS, 如果想知道其他字段设置:请移步官方文档
测试Mac的网页使用Windows的HTML即可,格式一致。
二、应用程序传参:
1、在Windows中
可在程序中使用 argparse.ArgumentParser() 方法设置参数
对传入的参数进行处理:
# 使用到urlparse模块对url进行解析
options, argv_rest = parser.parse_known_args(argv[1:])
if options.login_settings:
parsed_result = urlparse(options.login_settings).query
result = {k: v[0] for k, v in parse_qs(parsed_result).items()}
if result.get('token'):
print("设置Token:", result['token'])
参数设置的具体方法,可参考:https://blog.csdn.net/qq_42571592/article/details/122179398
2、在Mac中
MacOS下相对比较简单,其中 Qt 的方式非常简单,只需要响应应用的 QFileOpen 事件即可实现此功能,代码如下。
Qt实现方法
bool FileOpenEventFilter::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::FileOpen)
{
QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
if (!fileEvent->url().isEmpty())
{
m_lastUrl = fileEvent->url().toString();
emit urlOpened(m_lastUrl);
}
else if (!fileEvent->file().isEmpty())
{
emit fileOpened(fileEvent->file());
}
return false;
}
else
{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
使用pyqt5实现方法与思路:
定义槽,具体槽的使用可看文章: https://blog.csdn.net/m0_37329910/article/details/86571800
1、声明带QUrl参数的信号
from AnyQt.QtCore import QUrl, pyqtSignal as Signal
self.fileOpenRequest = Signal(QUrl)
2、定义槽函数
def record_path(url: QUrl):
if url.toString().startswith("myscheme"):
parsed_result = urlparse(url.toString()).query
result = {k: v[0] for k, v in parse_qs(parsed_result).items()}
if result.get('token'):
print("设置Token:", result['token'])
else:
path = url.toLocalFile() # 本地文件路径
if os.path.exists(path): # 如果文件存在则打开
print("打开文件的路径为:", path)
3、将信号连接到指定槽函数
self.fileOpenRequest.connect(record_path)
4、发射信号
def event(self, event):
if event.type() == QEvent.FileOpen: # 对请求进行判断
self.fileOpenRequest.emit(event.url())
elif event.type() == QEvent.PolishRequest:
print("正常启动")
return super().event(event)
代码截图:
注意:目前此方法只支持Mac系统
mac传参流程及原理总结:
流程
使用浏览器启动应用时,QEvent进行监听,当event.type()为 QEvent.FileOpen时,对event进行处理。
原理:QEvent::FileOpen方法用于应用启动的两种方式:
- 方式一:在浏览器中启动,在浏览器搜索栏输入: MYSCHEME://?token=fjasfjasndfnas,此时应用接收到的为:PyQt5.QtCore.QUrl(‘MYSCHEME://?token=fjasfjasndfnas’)
- 方式二:以此应用程序作为默认打开文件的方式唤起。或者将要使用此应用打开的文件拖到应用的图标上,唤起应用。此时应用接收到的为:PyQt5.QtCore.QUrl(‘file://文件本地路径’)
所以,两种方式其实都是走的DNS格式,只需对这两种参数进行不同的处理,本地文件在应用中打开文件,浏览器的参数则进行处理。
三、总结下Windows和Mac的实现方法:
Windows下:
- 在注册表中注册 URL Scheme 到系统
- 浏览器启动程序时,参数按照占位符格式传参
- 应用启动时接收相关参数,并对其进行处理 「使用到的设置参数方法为:argparse.ArgumentParser()」
Mac下:
- 通过 Info.plist 将 URL Scheme 注册到系统
- 浏览器启动程序时,参数走的是event,然后在event中,对参数进行处理「使用到的方法为:QEvent.FileOpen」
两者的区别:
- Windows下注册表中限制了命令的传参方式,所以浏览器启动最终落实为命令行启动,传参的话,我想到的方法为使用argparse.ArgumentParser()定义参数。
- Mac系统下,没对启动命令进行限制,所以只能通过QEvent进行监听,从而实现启动应用传参。
四、参考文章:
Qt 通过自定义 URL Scheme 给已经运行的应用传参(Windows&macOS)
PyQt5官网
Mac开发者
PyQt 5信号与槽的几种高级玩法
QT论坛
欢迎大家在评论区留言,知无不言,言无不尽。感觉不错的话,别忘了点赞收藏哦!
更多推荐
所有评论(0)