Skip to content

Commit 2e62a66

Browse files
update metadata thumbnail
1 parent 508dbe9 commit 2e62a66

21 files changed

+1632
-158
lines changed

base.py

Whitespace-only changes.

data/db.sqlite3

132 KB
Binary file not shown.

data/montage.tiff

89 MB
Binary file not shown.

datas.py

Whitespace-only changes.

load_js.py

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
# -*- coding: utf-8 -*-
2+
import sys
3+
import os
4+
import json
5+
import time
6+
7+
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QHBoxLayout, QSizePolicy
8+
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
9+
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile, QWebEngineSettings
10+
from PyQt5.QtCore import pyqtSlot, QEvent, Qt
11+
from PyQt5 import QtGui
12+
from PyQt5 import QtCore
13+
from need.utils.common.logger import svt_logger
14+
from need.utils.qutil import qtutils
15+
from need.settings import proj_root
16+
17+
18+
class RequestInterceptor(QWebEngineUrlRequestInterceptor):
19+
20+
def interceptRequest(self, info):
21+
url = info.requestUrl().toString()
22+
print("interceptRequest:", url, info.requestMethod())
23+
24+
25+
source_data = """'E:/projects/qt_practice/OpenSeaDragonDemo/GeneratedImages/target_files/',"""
26+
first_half = """ var viewer = OpenSeadragon({{
27+
id:'openseadragon1',
28+
prefixUrl: '{root}/static/images/',
29+
showNavigator: '1',
30+
showRotationControl: '1',
31+
showFlipControl: '1',
32+
navigatorSizeRatio: '0.2',
33+
navigatorMaintainSizeRatio: '1',
34+
navigatorBackground: 'transparent',
35+
navigatorBorderColor: 'transparent',
36+
fullPage: '1',
37+
// fullPageButton: 'vFullScreen',
38+
tileSources: {{
39+
Image: {{
40+
xmlns: 'http://schemas.microsoft.com/deepzoom/2009',
41+
Url: """.format(root=proj_root)
42+
last_half = """
43+
Overlap: '1',
44+
TileSize: '128',
45+
Format : 'jpeg',
46+
Size:{{
47+
Height: '{height}',
48+
Width: '{width}',
49+
}}
50+
}}
51+
}}
52+
}});
53+
viewer.canvas.addEventListener('contextmenu', function(event) {{
54+
event.preventDefault();
55+
}});
56+
viewer.scalebar({{
57+
type: OpenSeadragon.ScalebarType.MAP,
58+
pixelsPerMeter: 1e7,
59+
minWidth: "75px",
60+
location: OpenSeadragon.ScalebarLocation.BOTTOM_LEFT,
61+
xOffset: 5,
62+
yOffset: 10,
63+
stayInsideImage: true,
64+
color: "rgb(150, 150, 150)",
65+
fontColor: "rgb(100, 100, 100)",
66+
backgroundColor: "rgba(255, 255, 255, 0.5)",
67+
fontSize: "small",
68+
barThickness: 2
69+
}});
70+
"""
71+
72+
script = first_half + source_data + last_half
73+
74+
75+
class WebEnginePage(QWebEnginePage):
76+
def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID):
77+
# print("javaScriptConsoleMessage: ", level, message, lineNumber, sourceID)
78+
svt_logger.info("javaScriptConsoleMessage: ", level, message, lineNumber)
79+
80+
81+
class MainWindow(QMainWindow):
82+
def __init__(self, parent=None):
83+
super(MainWindow, self).__init__(parent)
84+
# self.dockWidget = QDockWidget()
85+
# self.dockWidget.DockWidgetClosable = 0
86+
self.setWindowTitle("切片浏览")
87+
self.form_widget = FormWidget(self)
88+
# _widget = QWidget()
89+
_layout = QHBoxLayout()
90+
_layout.addWidget(self.form_widget)
91+
self.setLayout(_layout)
92+
93+
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
94+
sizePolicy.setHeightForWidth(self.form_widget.sizePolicy().hasHeightForWidth())
95+
self.form_widget.setSizePolicy(sizePolicy)
96+
self.form_widget.setMinimumSize(QtCore.QSize(1200, 800))
97+
# self.form_widget.setMaximumSize(QtCore.QSize(1800, 1760))
98+
self.setCentralWidget(self.form_widget)
99+
100+
101+
class FormWidget(QWidget):
102+
def __init__(self, parent=None):
103+
super(FormWidget, self).__init__(parent)
104+
self.setWindowTitle("切片浏览")
105+
icon = QtGui.QIcon()
106+
icon.addPixmap(QtGui.QPixmap(":/icons/icons/image_view.png"))
107+
self.setWindowIcon(icon)
108+
self.script = ""
109+
self.__controls()
110+
vbox = QVBoxLayout()
111+
vbox.addWidget(self.browser)
112+
self.setLayout(vbox)
113+
# self.__layout()
114+
115+
def __controls(self):
116+
html_path = proj_root + r"/static/index.html"
117+
html = open(html_path, 'r', encoding='UTF-8').read()
118+
# print("html", html)
119+
self.browser = QWebEngineView()
120+
# self.browser.page().profile().defaultProfile().setRequestInterceptor(RequestInterceptor(self))
121+
122+
self.browser.setPage(WebEnginePage(self.browser))
123+
self.browser.setHtml(html)
124+
self.browser.setHtml(html, QtCore.QUrl.fromLocalFile(os.path.dirname(os.path.realpath(__file__))))
125+
# self.browser.load(QtCore.QUrl.fromLocalFile(os.path.abspath("index.html")))
126+
self.browser.settings().setAttribute(QWebEngineSettings.FullScreenSupportEnabled, True)
127+
self.browser.settings().setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
128+
# self.browser.settings().setAttribute(QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
129+
# self.browser.page().fullScreenRequested.connect(
130+
# lambda request, browser=self.browser: self.handle_fullscreen_requested(
131+
# request, browser
132+
# )
133+
# )
134+
self.browser.loadFinished.connect(self.onLoadFinished)
135+
136+
def onLoadFinished(self, ok):
137+
if ok:
138+
self.browser.page().runJavaScript(self.script, self.ready)
139+
140+
@pyqtSlot(str)
141+
def reload(self, source):
142+
image_info_path = "/".join(source[1:].split("/")[:-2]) + "/info.json"
143+
print("image_info_path", image_info_path)
144+
if not os.path.exists(image_info_path):
145+
return
146+
with open(image_info_path) as f:
147+
image_info = json.load(f)
148+
img_width = image_info.get("width")
149+
img_height = image_info.get("height")
150+
input_script = first_half + source + last_half.format(width=img_width, height=img_height)
151+
# print("full input_script", input_script)
152+
if self.script != input_script:
153+
self.script = input_script
154+
# print("self.script in reload", self.script)
155+
# self.browser.page().runJavaScript(script, self.ready)
156+
self.browser.reload()
157+
158+
def __layout(self):
159+
# self.vbox = QVBoxLayout()
160+
self.hBox = QVBoxLayout()
161+
self.hBox.addWidget(self.browser)
162+
# self.vbox.addLayout(self.hBox)
163+
self.setLayout(self.hBox)
164+
165+
def ready(self, returnValue):
166+
print(returnValue)
167+
self.browser.page().runJavaScript("viewer.setFullPage(!0);")
168+
169+
def handle_fullscreen_requested(self, request, browser):
170+
request.accept()
171+
print("request.toggleOn()", request.toggleOn())
172+
if request.toggleOn():
173+
self.showMaximized()
174+
175+
def changeEvent(self, e):
176+
# print("e in changeEvent", e.type())
177+
# print("window state in changeEvent", int(self.windowState()))
178+
if e.type() == QEvent.WindowStateChange:
179+
self.browser.page().runJavaScript("viewer.fullPageButton.onRelease()", self.ready)
180+
# if self.windowState() == Qt.WindowMaximized or self.windowState() == Qt.WindowFullScreen:
181+
# self.showMaximized()
182+
# self.browser.page().runJavaScript("viewer.setFullPage(!0);")
183+
super().changeEvent(e)
184+
185+
186+
def main():
187+
# os.environ["QTWEBENGINE_REMOTE_DEBUGGING"] = "8888"
188+
app = QApplication(sys.argv)
189+
windowGeometry = app.desktop().availableGeometry(0)
190+
print("windowGeometry", windowGeometry)
191+
192+
# win = MainWindow()
193+
# win.setMinimumSize(1700, 1600)
194+
# win.show()
195+
# widget = win.form_widget
196+
# widget.move(windowGeometry.topLeft())
197+
# widget.resize(windowGeometry.size())
198+
# loop = QEventLoop()
199+
# QTimer.singleShot(2000, loop.quit)
200+
# loop.exec_()
201+
# win.form_widget.reload("""'E:/data/20211212_18/target/target_files/',""")
202+
#
203+
# win2 = MainWindow()
204+
# # win.setMinimumSize(1700, 1600)
205+
# win2.show()
206+
# widget = win2.form_widget
207+
# widget.move(windowGeometry.topLeft())
208+
# widget.resize(windowGeometry.size())
209+
# loop = QEventLoop()
210+
# QTimer.singleShot(2000, loop.quit)
211+
# loop.exec_()
212+
# win2.form_widget.reload("""'E:/projects/NeatSvtScanRefa/data/20211221_27/target/target_files/',""")
213+
form_widget = FormWidget()
214+
form_widget.setMinimumSize(1200, 1000)
215+
form_widget.reload("""'E:/projects/NeatSvtScan/data/20220301_28/target/target_files/',""")
216+
form_widget.show()
217+
218+
# dw = QWebEngineView()
219+
# dw.setWindowTitle('开发人员工具')
220+
# dw.load(QtCore.QUrl('http://127.0.0.1:8888'))
221+
# dw.move(600, 100)
222+
# dw.show()
223+
224+
return app.exec_()
225+
226+
227+
if __name__ == '__main__':
228+
sys.exit(main())

main.py

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
import sys
33
import os
44
import json
5+
from django.http import HttpResponse
56

67
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QHBoxLayout, QSizePolicy
7-
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
8+
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlSchemeHandler
89
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile, QWebEngineSettings
9-
from PyQt5.QtCore import pyqtSlot, QEvent, Qt
10+
from PyQt5.QtWebChannel import QWebChannel
11+
from PyQt5.QtCore import pyqtSlot, QEvent, QObject, QByteArray, QBuffer, QIODevice
1012
from PyQt5 import QtGui
1113
from PyQt5 import QtCore
1214

15+
from open_tiff import source
16+
1317

1418
BASE_DIR = os.path.dirname(__file__)
1519

@@ -19,6 +23,20 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
1923
def interceptRequest(self, info):
2024
url = info.requestUrl().toString()
2125
print("interceptRequest:", url, info.requestMethod())
26+
if url.endswith("thumbnail.png"):
27+
print("interceptRequest get thumbnail.png:", url, info.navigationType())
28+
29+
30+
class UrlSchemeHandler(QWebEngineUrlSchemeHandler):
31+
32+
def requestStarted(self, job):
33+
url = job.requestUrl().toString()
34+
print("requestStarted in UrlSchemeHandler", url)
35+
if url.endswith("thumbnail.png"):
36+
# file = QFile('Data/app.png', job)
37+
# file.open(QIODevice.ReadOnly)
38+
# job.reply(b'image/png', file)
39+
print("requestStarted get thumbnail.png:", url)
2240

2341

2442
class WebEnginePage(QWebEnginePage):
@@ -44,6 +62,69 @@ def __init__(self, parent=None):
4462
self.setCentralWidget(self.form_widget)
4563

4664

65+
class Bridge(QObject):
66+
67+
def __init__(self, parent=None):
68+
super().__init__(parent)
69+
70+
@QtCore.pyqtSlot(int, result=str)
71+
def get_bands(self, idx):
72+
print("step into Bridge get_bands", idx)
73+
band_infos = source.getBandInformation()
74+
print("band_infos return", json.dumps(band_infos))
75+
return json.dumps(band_infos)
76+
77+
@pyqtSlot(result=str)
78+
def get_color_maps(self):
79+
simple = {
80+
'red': ['#000', '#f00'],
81+
'r': ['#000', '#f00'],
82+
'green': ['#000', '#0f0'],
83+
'g': ['#000', '#0f0'],
84+
'blue': ['#000', '#00f'],
85+
'b': ['#000', '#00f'],
86+
}
87+
cmaps = {}
88+
try:
89+
import matplotlib.pyplot
90+
91+
cmaps['matplotlib'] = list(matplotlib.pyplot.colormaps())
92+
except ImportError: # pragma: no cover
93+
raise Exception('Install matplotlib for additional colormap choices.')
94+
cmaps['simple'] = [s for s in simple.keys() if len(s) > 1]
95+
96+
return json.dumps(cmaps)
97+
98+
@pyqtSlot(result=str)
99+
def get_metadata(self):
100+
metadata = source.getMetadata()
101+
return json.dumps(metadata)
102+
103+
@pyqtSlot(result=QByteArray)
104+
def get_thumbnail(self):
105+
print("get into get_thumbnail")
106+
encoding = 'PNG'
107+
width = 256
108+
height = 256
109+
thumb_data, mime_type = source.getThumbnail(encoding=encoding, width=width, height=height)
110+
# buf = QBuffer()
111+
# buf.open(QIODevice.WriteOnly)
112+
# buf.write(thumb_data)
113+
# buf.seek(0)
114+
# buf.close()
115+
# print("get_thumbnail thumb_data before return", type(buf), buf.size())
116+
return QByteArray(thumb_data).toBase64()
117+
118+
@QtCore.pyqtSlot(int, result=int)
119+
def getRef(self, x):
120+
print("inside getRef", x)
121+
return x + 5
122+
123+
@QtCore.pyqtSlot(int)
124+
def printRef(self, ref):
125+
print("inside printRef", ref)
126+
127+
47128
class FormWidget(QWidget):
48129
def __init__(self, parent=None):
49130
super(FormWidget, self).__init__(parent)
@@ -52,6 +133,9 @@ def __init__(self, parent=None):
52133
icon.addPixmap(QtGui.QPixmap(":/icons/icons/image_view.png"))
53134
self.setWindowIcon(icon)
54135
self.script = ""
136+
self._script = open('static/qwebchannel.js', 'rb').read().decode()
137+
self.bridge = Bridge(self)
138+
# self.channel.registerObject('Bridge', self)
55139
self.__controls()
56140
vbox = QVBoxLayout()
57141
vbox.addWidget(self.browser)
@@ -62,25 +146,29 @@ def __controls(self):
62146
html_path = BASE_DIR + r"/static/index.html"
63147
html = open(html_path, 'r', encoding='UTF-8').read()
64148
self.browser = QWebEngineView()
149+
# self.browser.setPage(WebEnginePage(self.browser))
65150
self.browser.page().profile().defaultProfile().setRequestInterceptor(RequestInterceptor(self))
151+
self.browser.page().profile().defaultProfile().installUrlSchemeHandler(b'api', UrlSchemeHandler(self.browser))
152+
self.channel = QWebChannel(self.browser.page())
66153

67-
self.browser.setPage(WebEnginePage(self.browser))
68-
self.browser.setHtml(html)
69-
self.browser.setHtml(html, QtCore.QUrl.fromLocalFile(os.path.dirname(os.path.realpath(__file__))))
70-
# self.browser.load(QtCore.QUrl.fromLocalFile(os.path.abspath("index.html")))
154+
self.browser.page().setWebChannel(self.channel)
155+
self.channel.registerObject('Bridge', self.bridge)
156+
157+
# self.browser.setHtml(html)
158+
# self.browser.setHtml(html, QtCore.QUrl.fromLocalFile(os.path.dirname(os.path.realpath(__file__))))
159+
self.browser.load(QtCore.QUrl.fromLocalFile(os.path.abspath(html_path)))
71160
self.browser.settings().setAttribute(QWebEngineSettings.FullScreenSupportEnabled, True)
72161
self.browser.settings().setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
73162
# self.browser.settings().setAttribute(QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
74-
# self.browser.page().fullScreenRequested.connect(
75-
# lambda request, browser=self.browser: self.handle_fullscreen_requested(
76-
# request, browser
77-
# )
78-
# )
79-
# self.browser.loadFinished.connect(self.onLoadFinished)
163+
# self.browser.page().loadFinished.connect(self.onLoadFinished)
80164
#
81165
# def onLoadFinished(self, ok):
82166
# if ok:
83-
# self.browser.page().runJavaScript(self.script, self.ready)
167+
# self.browser.page().runJavaScript(self._script)
168+
169+
@pyqtSlot()
170+
def get_metadata(self):
171+
print("get_metadata")
84172

85173
@pyqtSlot(str)
86174
def reload(self, source):

metadata.py

Whitespace-only changes.

models.py

Whitespace-only changes.

0 commit comments

Comments
 (0)