如何使用 HTML 按钮关闭应用程序
How To Close Application Using HTML Button
在我的 PyQt5 浏览器中 window 我加载了 HTML 和 JavaScript。我在 HTML 中添加了一个按钮,该按钮应该使用 vanilla JavaScript 关闭 Python-Application。这是我的 Python 代码,它生成 window 并加载 HTML-File:
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()
-函数时关闭应用程序?
首先要知道关闭window和退出应用是不一样的,如果你只有一个window和属性 quitOnLastWindowClosed in 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>
在我的 PyQt5 浏览器中 window 我加载了 HTML 和 JavaScript。我在 HTML 中添加了一个按钮,该按钮应该使用 vanilla JavaScript 关闭 Python-Application。这是我的 Python 代码,它生成 window 并加载 HTML-File:
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()
-函数时关闭应用程序?
首先要知道关闭window和退出应用是不一样的,如果你只有一个window和属性 quitOnLastWindowClosed in 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>