I'm trying to load a 3d model file through javascript using QWebEngineView in PyQt5. I can successfully load the html file and the javascript file but the javascript file has to load a 3d model file in my local disk drive. I get this error "URL scheme "file" is not supported. js: TypeError: Failed to fetch". As I already read in the Qt Documentation it allows any script to access files int the local machine by default. So i'm stuck with this problem for the moment. Does anyone have a clue to debug this problem ? Here are my files. (PS : This works when i use the Visual Studio Code Live Server)
main.py
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtWebEngineWidgets as QtWeb
from PyQt5.QtCore import QObject, pyqtSlot, QUrl, QVariant
import os
import sys
"""
class CallHandler(QObject):
@pyqtSlot(result=QVariant)
def test(self):
print('call received')
return QVariant({"abc": "def", "ab": 22})
# take an argument from javascript - JS: handler.test1('hello!')
@pyqtSlot(QVariant, result=QVariant)
def test1(self, args):
print('i got')
print(args)
return "ok"
"""
class WebView(QtWeb.QWebEngineView):
def __init__(self):
super(WebView, self).__init__()
#self.channel = QWebChannel()
#self.handler = CallHandler()
#self.channel.registerObject('handler', self.handler)
#self.page().setWebChannel(self.channel)
file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "index.html"))
local_url = QUrl.fromLocalFile(file_path)
self.load(local_url)
self.show()
if __name__ == "__main__":
sys.argv.append("--disable-web-security")
app = QApplication(sys.argv)
view = WebView()
#view.page().settings().setAttribute(QtWeb.QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
#view.page().settings().setAttribute(QtWeb.QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
app.exec_()
index.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie-edge"/>
<link rel="stylesheet" href="./style.css"/>
<title>proVACT</title>
</head>
<body>
<div class="scene"></div>
<script src="./three.min.js"></script>
<script src="./GLTFLoader.js"></script>
<script src="./app.js"></script>
</body>
</html>
style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
font-family: sans-serif;
overflow: hidden;
background: #000321;
}
.scene,
canvas{
position: absolute;
width: 100%;
height: 100%;
}
app.js
//Variables for Setup
let container;
let camera;
let renderer;
let scene;
let lancia;
function init(){
container = document.querySelector('.scene');
scene = new THREE.Scene();
const fov = 35;
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1;
const far = 500;
camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
camera.position.set(0, 0, 5);
const ambient = new THREE.AmbientLight(0x404040,5)
scene.add(ambient);
/*
const light = new THREE.DirectionalLight(0xffffff,1)
light.position.set(10, 10, 30);
scene.add(light);*/
renderer = new THREE.WebGLRenderer({antialias:true, alpha: true});
renderer.setSize(container.clientWidth, container.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
let loader = new THREE.GLTFLoader();
loader.load('./3D/render_lancia.gltf', function(gltf){
scene.add(gltf.scene);
lancia = gltf.scene.children[0];
lancia.rotation.order = 'YXZ';
renderer.render(scene, camera);
animate();
});
}
function animate(){
requestAnimationFrame(animate);
lancia.rotation.x += 0.01;
renderer.render(scene, camera);
}
init()