如何使用 HTML 按钮关闭应用程序
Posted
技术标签:
【中文标题】如何使用 HTML 按钮关闭应用程序【英文标题】:How To Close Application Using HTML Button 【发布时间】:2021-09-27 20:19:58 【问题描述】:在我的 PyQt5 浏览器窗口中,我已经加载了 html 和 javascript。我在 HTML 中包含了一个按钮,它应该使用 vanilla JavaScript 关闭 Python 应用程序。这是我创建窗口并加载 HTML 文件的 Python 代码:
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.browser = QWebEngineView()
config_name = 'data_files/init.html'
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
elif __file__:
application_path = os.path.dirname(__file__)
config_path = os.path.join(application_path, config_name)
self.browser.load(QUrl().fromLocalFile(config_path))
self.setCentralWidget(self.browser)
self.showMaximized()
app = QApplication(sys.argv)
QApplication.setApplicationName('v0.1')
window = MainWindow()
app.exec_()
在我的 HTML 中,我有这个:
<button onclick="exitApplication()">Exit</button>
<script>
function exitApplication()
// How can I tell Python to call self.close() ??
</script>
正如我所说,我想使用 HTML 中的按钮关闭应用程序。我查看了各种来源,但我从来没有找到任何可以帮助我或让我感到困惑的东西。
调用exitApplication()
-Function时如何关闭应用程序?
【问题讨论】:
【参考方案1】:首先要知道,关闭窗口和退出应用程序是不一样的,如果你只有一个窗口并且属性quitOnLastWindowClosed为True,那么它们是等价的,但一般情况下是不一样的。
QtWebChannel:
import sys
import os
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QCoreApplication, QObject, QUrl
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebChannel import QWebChannel
application_path = (
os.path.dirname(sys.executable)
if getattr(sys, "frozen", False)
else os.path.dirname(__file__)
)
class Bridge(QObject):
request_closed = pyqtSignal()
@pyqtSlot()
def quit(self):
QCoreApplication.quit()
@pyqtSlot()
def close(self):
self.request_closed.emit()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.browser = QWebEngineView()
self.bridge = Bridge()
self.bridge.request_closed.connect(self.close)
self.channel = QWebChannel()
self.channel.registerObject("bridge", self.bridge)
self.browser.page().setWebChannel(self.channel)
config_name = "data_files/init.html"
config_path = os.path.join(application_path, config_name)
self.browser.load(QUrl.fromLocalFile(config_path))
self.setCentralWidget(self.browser)
self.showMaximized()
if __name__ == "__main__":
app = QApplication(sys.argv)
QApplication.setApplicationName("v0.1")
window = MainWindow()
app.exec_()
<!DOCTYPE html>
<html>
<head>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<button onclick="exitApplication()">Exit</button>
<script>
var bridge = null;
function exitApplication()
bridge.quit();
// bridge.close();
if (typeof QWebChannel !== "undefined")
new QWebChannel(qt.webChannelTransport, function (channel)
bridge = channel.objects.bridge;
);
</script>
</body>
</html>
QWebEngineUrlSchemeHandler:
import sys
import os
from PyQt5.QtCore import QCoreApplication, QUrl
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWebEngineCore import (
QWebEngineUrlScheme,
QWebEngineUrlSchemeHandler,
QWebEngineUrlRequestJob,
)
from PyQt5.QtWebEngineWidgets import QWebEngineView
application_path = (
os.path.dirname(sys.executable)
if getattr(sys, "frozen", False)
else os.path.dirname(__file__)
)
class QtSchemeHandler(QWebEngineUrlSchemeHandler):
def requestStarted(self, job):
if job.requestMethod() == b"POST" and job.requestUrl() == QUrl(
"qt://commands/quit"
):
QCoreApplication.quit()
return
job.fail(QWebEngineUrlRequestJob.RequestFailed)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.browser = QWebEngineView()
self.scheme_handler = QtSchemeHandler()
self.browser.page().profile().installUrlSchemeHandler(
b"qt", self.scheme_handler
)
config_name = "data_files/init.html"
config_path = os.path.join(application_path, config_name)
self.browser.load(QUrl.fromLocalFile(config_path))
self.setCentralWidget(self.browser)
self.showMaximized()
if __name__ == "__main__":
scheme = QWebEngineUrlScheme(b"qt")
scheme.setFlags(QWebEngineUrlScheme.CorsEnabled)
QWebEngineUrlScheme.registerScheme(scheme)
app = QApplication(sys.argv)
QApplication.setApplicationName("v0.1")
window = MainWindow()
app.exec_()
<!DOCTYPE html>
<html>
<body>
<button onclick="exitApplication()">Exit</button>
<script>
function exitApplication()
const xhr = new XMLHttpRequest();
xhr.open("POST", "qt://commands/quit", true);
xhr.send();
</script>
</body>
</html>
【讨论】:
谢谢,我会试试这个!您能否在这里更详细地解释这部分:qrc:///qtwebchannel/qwebchannel.js
我不明白,这是一些额外的库,我找不到吗?这是正确的来源吗:doc.qt.io/archives/qt-5.9/…?
@Miger 你不需要做任何事情,因为该库包含在 Qt 中(qrc 是 Qt 的内部资源)
这很好,我会尽快尝试,如果检查成功,我会将其标记为已接受的答案。感谢您的帮助!
工作就像一个魅力,谢谢!以上是关于如何使用 HTML 按钮关闭应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用未完成按钮顶部栏的按钮关闭 inAppbrowser
单击inappbrowser中启动的页面上的按钮时如何关闭phonegap inappbrowser?