I am using windows 10, PyQt5, monaco and pyodide. I want to display a .html page on a desktop app, via PyQts libraries. The html file runs when I use it on the web, but not via a desktop app using PyWebEngineWidgets. However, when running with python 3.11, i get the error:
js: Uncaught (in promise) TypeError: wasm function signature contains illegal type
In addition to the app being stuck "loading pyodide", and not running the code. Despite my browser having its cache cleared, and being wasm compatible (opera gx, fully updated).
The python file is:
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QUrl
class MainWindow(QMainWindow):
def __init__(self):
self.browser.page().setDevToolsPage(self.browser.page())
super().__init__()
# Set up the main window
self.setWindowTitle("PyQt5 App with QWebEngineView")
self.setGeometry(100, 100, 800, 600)
# Create a QWebEngineView widget
self.browser = QWebEngineView()
# Use a local web server URL
url = QUrl("http://localhost:8000/monaco.html")
# Set the URL in QWebEngineView
self.browser.setUrl(url)
# Set up the layout
layout = QVBoxLayout()
layout.addWidget(self.browser)
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
and my .html file is
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Monaco Editor with Run Button for Python</title>
<style>
#editor { width: 100%; height: 400px; border: 1px solid #ccc; }
#output { margin-top: 10px; padding: 10px; background: #f4f4f4; border-radius: 5px; }
</style>
</head>
<body>
<button onclick="runCode()">Run Code</button>
<div id="editor"></div>
<pre id="output">Output will appear here...</pre>
<!-- Load Pyodide first -->
<script src=".23.4/full/pyodide.js"></script>
<!-- Load Monaco Editor -->
<script src=".37.0/min/vs/loader.js"></script>
<script>
// Initialize Monaco Editor
require.config({ paths: { 'vs': '.37.0/min/vs' }});
require(['vs/editor/editor.main'], function() {
window.editor = monaco.editor.create(document.getElementById('editor'), {
value: 'print("Hello, World!")', // Default Python code
language: 'python' // Set language to Python
});
});
// Load Pyodide (Python runtime for the browser)
let pyodide;
let pyodideLoading = false;
let pyodideLoaded = false;
async function initializePyodide() {
console.log("Loading Pyodide...");
pyodideLoading = true;
const outputElement = document.getElementById('output');
outputElement.innerText = "Loading Pyodide, please wait...";
try {
pyodide = await loadPyodide({
indexURL: ".23.4/full/"
});
console.log("Pyodide loaded successfully!");
pyodideLoaded = true;
outputElement.innerText = "Pyodide loaded successfully! You can now run Python code.";
} catch (err) {
console.error("Failed to load Pyodide:", err);
outputElement.innerText = "Failed to load Pyodide. Please check your internet connection and try again.";
} finally {
pyodideLoading = false;
}
}
// Start loading Pyodide
initializePyodide();
async function runCode() {
const code = window.editor.getValue();
const outputElement = document.getElementById('output');
if (!pyodideLoaded) {
outputElement.innerText = "Pyodide is still loading. Please wait...";
return;
}
try {
console.log("Running Python code...");
// Redirect stdout to capture print statements
await pyodide.runPythonAsync(`
import sys
from io import StringIO
sys.stdout = StringIO()
`);
// Run the user's code
await pyodide.runPythonAsync(code);
// Get the captured output
const output = await pyodide.runPythonAsync("sys.stdout.getvalue()");
outputElement.innerText = output || "Code ran successfully (no output).";
} catch (err) {
console.error("Error running Python code:", err);
outputElement.innerText = "Error: " + err.message;
}
}
</script>
</body>
</html>
Thanks for reading. Also note I am new with coding, and also with stack overflow.