-
-
Notifications
You must be signed in to change notification settings - Fork 90
/
q3dwebkitview.py
135 lines (95 loc) · 4.27 KB
/
q3dwebkitview.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-
# (C) 2016 Minoru Akagi
# SPDX-License-Identifier: GPL-2.0-or-later
# begin: 2016-02-10
import os
from PyQt5.QtCore import Qt, QSize, QUrl
from PyQt5.QtGui import QDesktopServices, QImage, QPainter
from PyQt5.QtWidgets import QDialog, QVBoxLayout
from PyQt5.QtWebKit import QWebSettings, QWebSecurityOrigin
from PyQt5.QtWebKitWidgets import QWebInspector, QWebPage, QWebView
from .conf import DEBUG_MODE
from .q3dwebviewcommon import Q3DWebPageCommon, Q3DWebViewCommon
class Q3DWebKitPage(Q3DWebPageCommon, QWebPage):
def __init__(self, parent=None):
QWebPage.__init__(self, parent)
Q3DWebPageCommon.__init__(self)
self.isWebEnginePage = False
def url(self):
return self.mainFrame().url()
def setup(self, settings, wnd=None):
"""wnd: Q3DWindow or None (off-screen mode)"""
Q3DWebPageCommon.setup(self, settings, wnd)
self.mainFrame().javaScriptWindowObjectCleared.connect(self.addJSObject)
# security settings
origin = self.mainFrame().securityOrigin()
origin.addAccessWhitelistEntry("http:", "*", QWebSecurityOrigin.AllowSubdomains)
origin.addAccessWhitelistEntry("https:", "*", QWebSecurityOrigin.AllowSubdomains)
self.setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
self.linkClicked.connect(QDesktopServices.openUrl)
# if self.offScreen:
# # transparent background
# palette = self.palette()
# palette.setBrush(QPalette.Base, Qt.transparent)
# self.setPalette(palette)
# #webview: self.setAttribute(Qt.WA_OpaquePaintEvent, False)
url = os.path.join(os.path.abspath(os.path.dirname(__file__)), "viewer", "webkit.html").replace("\\", "/")
self.myUrl = QUrl.fromLocalFile(url)
self.reload()
def addJSObject(self):
self.mainFrame().addToJavaScriptWindowObject("pyObj", self.bridge)
if DEBUG_MODE:
self.logToConsole("pyObj added")
def reload(self):
Q3DWebPageCommon.reload(self)
self.mainFrame().setUrl(self.myUrl)
def runScript(self, string, data=None, message="", sourceID="q3dview.py", callback=None, wait=False):
Q3DWebPageCommon.runScript(self, string, data, message, sourceID, callback, wait)
if data is not None:
self.bridge.setData(data)
result = self.mainFrame().evaluateJavaScript(string)
if callback:
callback(result)
return result
def sendData(self, data):
string = "loadJSONObject(pyData())"
if DEBUG_MODE:
self.logToConsole(string)
self.runScript(string, data, message=None)
def logToConsole(self, message, level="debug"):
self.mainFrame().evaluateJavaScript('console.{}("{}");'.format(level, message.replace('"', '\\"')))
def renderImage(self, width, height, callback):
old_size = self.viewportSize()
self.setViewportSize(QSize(width, height))
image = QImage(width, height, QImage.Format_ARGB32_Premultiplied)
painter = QPainter(image)
self.mainFrame().render(painter)
painter.end()
self.setViewportSize(old_size)
callback(image)
class Q3DWebKitView(Q3DWebViewCommon, QWebView):
def __init__(self, parent=None):
QWebView.__init__(self, parent)
Q3DWebViewCommon.__init__(self)
self._page = Q3DWebKitPage(self)
self._page.setObjectName("webKitPage")
self.setPage(self._page)
# security setting for billboard, model file and point cloud layer
self.settings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True)
# web inspector setting
self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
def showDevTools(self):
dlg = QDialog(self)
dlg.setAttribute(Qt.WA_DeleteOnClose)
dlg.resize(800, 500)
dlg.setWindowTitle("Qgis2threejs Web Inspector")
dlg.rejected.connect(self.devToolsClosed)
wi = QWebInspector(dlg)
wi.setPage(self._page)
v = QVBoxLayout()
v.setContentsMargins(0, 0, 0, 0)
v.addWidget(wi)
dlg.setLayout(v)
dlg.show()
def renderImage(self, width, height, callback, wnd=None):
self._page.renderImage(width, height, callback)