新增customplot网页版
parent
17ac8c113c
commit
bea1a6f73f
|
@ -0,0 +1,72 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
|
||||||
|
<!--Set visual viewport size for mobile devices to the device size,
|
||||||
|
witch results in a scale of 1 and a 1:1 mapping between CSS pixels
|
||||||
|
and Qt device independent pixels. -->
|
||||||
|
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=0"/>
|
||||||
|
|
||||||
|
<title>qcustomplotdemo</title>
|
||||||
|
<style>
|
||||||
|
/* Make the html body cover the entire (visual) viewport with no scroll bars. */
|
||||||
|
html, body { padding: 0; margin: 0; overflow:hidden; height: 100vh }
|
||||||
|
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||||
|
canvas { border: 0px none; background-color: white; height:100%; width:100%; }
|
||||||
|
/* The contenteditable property is set to true for the canvas in order to support
|
||||||
|
clipboard events. Hide the resulting focus frame and set the cursor back to
|
||||||
|
the default cursor. */
|
||||||
|
canvas { outline: 0px solid transparent; caret-color: transparent; cursor:default }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body onload="init()">
|
||||||
|
<figure style="overflow:visible;" id="qtspinner">
|
||||||
|
<center style="margin-top:1.5em; line-height:150%">
|
||||||
|
<img src="qtlogo.svg" width="320" height="200" style="display:block"></img>
|
||||||
|
<strong>Qt for WebAssembly: qcustomplotdemo</strong>
|
||||||
|
<div id="qtstatus"></div>
|
||||||
|
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
|
||||||
|
</center>
|
||||||
|
</figure>
|
||||||
|
<canvas id="qtcanvas" oncontextmenu="event.preventDefault()" contenteditable="true"></canvas>
|
||||||
|
|
||||||
|
<script type='text/javascript'>
|
||||||
|
function init() {
|
||||||
|
var spinner = document.querySelector('#qtspinner');
|
||||||
|
var canvas = document.querySelector('#qtcanvas');
|
||||||
|
var status = document.querySelector('#qtstatus')
|
||||||
|
|
||||||
|
var qtLoader = QtLoader({
|
||||||
|
canvasElements : [canvas],
|
||||||
|
showLoader: function(loaderStatus) {
|
||||||
|
spinner.style.display = 'block';
|
||||||
|
canvas.style.display = 'none';
|
||||||
|
status.innerHTML = loaderStatus + "...";
|
||||||
|
},
|
||||||
|
showError: function(errorText) {
|
||||||
|
status.innerHTML = errorText;
|
||||||
|
spinner.style.display = 'block';
|
||||||
|
canvas.style.display = 'none';
|
||||||
|
},
|
||||||
|
showExit: function() {
|
||||||
|
status.innerHTML = "Application exit";
|
||||||
|
if (qtLoader.exitCode !== undefined)
|
||||||
|
status.innerHTML += " with code " + qtLoader.exitCode;
|
||||||
|
if (qtLoader.exitText !== undefined)
|
||||||
|
status.innerHTML += " (" + qtLoader.exitText + ")";
|
||||||
|
spinner.style.display = 'block';
|
||||||
|
canvas.style.display = 'none';
|
||||||
|
},
|
||||||
|
showCanvas: function() {
|
||||||
|
spinner.style.display = 'none';
|
||||||
|
canvas.style.display = 'block';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
qtLoader.loadEmscriptenModule("qcustomplotdemo");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="qtloader.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -0,0 +1,577 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// QtLoader provides javascript API for managing Qt application modules.
|
||||||
|
//
|
||||||
|
// QtLoader provides API on top of Emscripten which supports common lifecycle
|
||||||
|
// tasks such as displaying placeholder content while the module downloads,
|
||||||
|
// handing application exits, and checking for browser wasm support.
|
||||||
|
//
|
||||||
|
// There are two usage modes:
|
||||||
|
// * Managed: QtLoader owns and manages the HTML display elements like
|
||||||
|
// the loader and canvas.
|
||||||
|
// * External: The embedding HTML page owns the display elements. QtLoader
|
||||||
|
// provides event callbacks which the page reacts to.
|
||||||
|
//
|
||||||
|
// Managed mode usage:
|
||||||
|
//
|
||||||
|
// var config = {
|
||||||
|
// containerElements : [$("container-id")];
|
||||||
|
// }
|
||||||
|
// var qtLoader = QtLoader(config);
|
||||||
|
// qtLoader.loadEmscriptenModule("applicationName");
|
||||||
|
//
|
||||||
|
// External mode.usage:
|
||||||
|
//
|
||||||
|
// var config = {
|
||||||
|
// canvasElements : [$("canvas-id")],
|
||||||
|
// showLoader: function() {
|
||||||
|
// loader.style.display = 'block'
|
||||||
|
// canvas.style.display = 'hidden'
|
||||||
|
// },
|
||||||
|
// showCanvas: function() {
|
||||||
|
// loader.style.display = 'hidden'
|
||||||
|
// canvas.style.display = 'block'
|
||||||
|
// return canvas;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// var qtLoader = QtLoader(config);
|
||||||
|
// qtLoader.loadEmscriptenModule("applicationName");
|
||||||
|
//
|
||||||
|
// Config keys
|
||||||
|
//
|
||||||
|
// containerElements : [container-element, ...]
|
||||||
|
// One or more HTML elements. QtLoader will display loader elements
|
||||||
|
// on these while loading the applicaton, and replace the loader with a
|
||||||
|
// canvas on load complete.
|
||||||
|
// canvasElements : [canvas-element, ...]
|
||||||
|
// One or more canvas elements.
|
||||||
|
// showLoader : function(status, containerElement)
|
||||||
|
// Optional loading element constructor function. Implement to create
|
||||||
|
// a custom loading screen. This function may be called multiple times,
|
||||||
|
// while preparing the application binary. "status" is a string
|
||||||
|
// containing the loading sub-status, and may be either "Downloading",
|
||||||
|
// or "Compiling". The browser may be using streaming compilation, in
|
||||||
|
// which case the wasm module is compiled during downloading and the
|
||||||
|
// there is no separate compile step.
|
||||||
|
// showCanvas : function(containerElement)
|
||||||
|
// Optional canvas constructor function. Implement to create custom
|
||||||
|
// canvas elements.
|
||||||
|
// showExit : function(crashed, exitCode, containerElement)
|
||||||
|
// Optional exited element constructor function.
|
||||||
|
// showError : function(crashed, exitCode, containerElement)
|
||||||
|
// Optional error element constructor function.
|
||||||
|
//
|
||||||
|
// path : <string>
|
||||||
|
// Prefix path for wasm file, realative to the loading HMTL file.
|
||||||
|
// restartMode : "DoNotRestart", "RestartOnExit", "RestartOnCrash"
|
||||||
|
// Controls whether the application should be reloaded on exits. The default is "DoNotRestart"
|
||||||
|
// restartType : "RestartModule", "ReloadPage"
|
||||||
|
// restartLimit : <int>
|
||||||
|
// Restart attempts limit. The default is 10.
|
||||||
|
// stdoutEnabled : <bool>
|
||||||
|
// stderrEnabled : <bool>
|
||||||
|
// environment : <object>
|
||||||
|
// key-value environment variable pairs.
|
||||||
|
//
|
||||||
|
// QtLoader object API
|
||||||
|
//
|
||||||
|
// webAssemblySupported : bool
|
||||||
|
// webGLSupported : bool
|
||||||
|
// canLoadQt : bool
|
||||||
|
// Reports if WebAssembly and WebGL are supported. These are requirements for
|
||||||
|
// running Qt applications.
|
||||||
|
// loadEmscriptenModule(applicationName)
|
||||||
|
// Loads the application from the given emscripten javascript module file and wasm file
|
||||||
|
// status
|
||||||
|
// One of "Created", "Loading", "Running", "Exited".
|
||||||
|
// crashed
|
||||||
|
// Set to true if there was an unclean exit.
|
||||||
|
// exitCode
|
||||||
|
// main()/emscripten_force_exit() return code. Valid on status change to
|
||||||
|
// "Exited", iff crashed is false.
|
||||||
|
// exitText
|
||||||
|
// Abort/exit message.
|
||||||
|
// addCanvasElement
|
||||||
|
// Add canvas at run-time. Adds a corresponding QScreen,
|
||||||
|
// removeCanvasElement
|
||||||
|
// Remove canvas at run-time. Removes the corresponding QScreen.
|
||||||
|
// resizeCanvasElement
|
||||||
|
// Signals to the application that a canvas has been resized.
|
||||||
|
// setFontDpi
|
||||||
|
// Sets the logical font dpi for the application.
|
||||||
|
|
||||||
|
|
||||||
|
var Module = {}
|
||||||
|
|
||||||
|
function QtLoader(config)
|
||||||
|
{
|
||||||
|
function webAssemblySupported() {
|
||||||
|
return typeof WebAssembly !== "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
function webGLSupported() {
|
||||||
|
// We expect that WebGL is supported if WebAssembly is; however
|
||||||
|
// the GPU may be blacklisted.
|
||||||
|
try {
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
return !!(window.WebGLRenderingContext && (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")));
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function canLoadQt() {
|
||||||
|
// The current Qt implementation requires WebAssembly (asm.js is not in use),
|
||||||
|
// and also WebGL (there is no raster fallback).
|
||||||
|
return webAssemblySupported() && webGLSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeChildren(element) {
|
||||||
|
while (element.firstChild) element.removeChild(element.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCanvas() {
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
canvas.className = "QtCanvas";
|
||||||
|
canvas.style.height = "100%";
|
||||||
|
canvas.style.width = "100%";
|
||||||
|
|
||||||
|
// Set contentEditable in order to enable clipboard events; hide the resulting focus frame.
|
||||||
|
canvas.contentEditable = true;
|
||||||
|
canvas.style.outline = "0px solid transparent";
|
||||||
|
canvas.style.caretColor = "transparent";
|
||||||
|
canvas.style.cursor = "default";
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default state handler functions and create canvases if needed
|
||||||
|
if (config.containerElements !== undefined) {
|
||||||
|
|
||||||
|
config.canvasElements = config.containerElements.map(createCanvas);
|
||||||
|
|
||||||
|
config.showError = config.showError || function(errorText, container) {
|
||||||
|
removeChildren(container);
|
||||||
|
var errorTextElement = document.createElement("text");
|
||||||
|
errorTextElement.className = "QtError"
|
||||||
|
errorTextElement.innerHTML = errorText;
|
||||||
|
return errorTextElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.showLoader = config.showLoader || function(loadingState, container) {
|
||||||
|
removeChildren(container);
|
||||||
|
var loadingText = document.createElement("text");
|
||||||
|
loadingText.className = "QtLoading"
|
||||||
|
loadingText.innerHTML = '<p><center> ${loadingState}...</center><p>';
|
||||||
|
return loadingText;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.showCanvas = config.showCanvas || function(canvas, container) {
|
||||||
|
removeChildren(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.showExit = config.showExit || function(crashed, exitCode, container) {
|
||||||
|
if (!crashed)
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
removeChildren(container);
|
||||||
|
var fontSize = 54;
|
||||||
|
var crashSymbols = ["\u{1F615}", "\u{1F614}", "\u{1F644}", "\u{1F928}", "\u{1F62C}",
|
||||||
|
"\u{1F915}", "\u{2639}", "\u{1F62E}", "\u{1F61E}", "\u{1F633}"];
|
||||||
|
var symbolIndex = Math.floor(Math.random() * crashSymbols.length);
|
||||||
|
var errorHtml = `<font size='${fontSize}'> ${crashSymbols[symbolIndex]} </font>`
|
||||||
|
var errorElement = document.createElement("text");
|
||||||
|
errorElement.className = "QtExit"
|
||||||
|
errorElement.innerHTML = errorHtml;
|
||||||
|
return errorElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.restartMode = config.restartMode || "DoNotRestart";
|
||||||
|
config.restartLimit = config.restartLimit || 10;
|
||||||
|
|
||||||
|
if (config.stdoutEnabled === undefined) config.stdoutEnabled = true;
|
||||||
|
if (config.stderrEnabled === undefined) config.stderrEnabled = true;
|
||||||
|
|
||||||
|
// Make sure config.path is defined and ends with "/" if needed
|
||||||
|
if (config.path === undefined)
|
||||||
|
config.path = "";
|
||||||
|
if (config.path.length > 0 && !config.path.endsWith("/"))
|
||||||
|
config.path = config.path.concat("/");
|
||||||
|
|
||||||
|
if (config.environment === undefined)
|
||||||
|
config.environment = {};
|
||||||
|
|
||||||
|
var publicAPI = {};
|
||||||
|
publicAPI.webAssemblySupported = webAssemblySupported();
|
||||||
|
publicAPI.webGLSupported = webGLSupported();
|
||||||
|
publicAPI.canLoadQt = canLoadQt();
|
||||||
|
publicAPI.canLoadApplication = canLoadQt();
|
||||||
|
publicAPI.status = undefined;
|
||||||
|
publicAPI.loadEmscriptenModule = loadEmscriptenModule;
|
||||||
|
publicAPI.addCanvasElement = addCanvasElement;
|
||||||
|
publicAPI.removeCanvasElement = removeCanvasElement;
|
||||||
|
publicAPI.resizeCanvasElement = resizeCanvasElement;
|
||||||
|
publicAPI.setFontDpi = setFontDpi;
|
||||||
|
publicAPI.fontDpi = fontDpi;
|
||||||
|
|
||||||
|
restartCount = 0;
|
||||||
|
|
||||||
|
function fetchResource(filePath) {
|
||||||
|
var fullPath = config.path + filePath;
|
||||||
|
return fetch(fullPath).then(function(response) {
|
||||||
|
if (!response.ok) {
|
||||||
|
self.error = response.status + " " + response.statusText + " " + response.url;
|
||||||
|
setStatus("Error");
|
||||||
|
return Promise.reject(self.error)
|
||||||
|
} else {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchText(filePath) {
|
||||||
|
return fetchResource(filePath).then(function(response) {
|
||||||
|
return response.text();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchThenCompileWasm(response) {
|
||||||
|
return response.arrayBuffer().then(function(data) {
|
||||||
|
self.loaderSubState = "Compiling";
|
||||||
|
setStatus("Loading") // trigger loaderSubState udpate
|
||||||
|
return WebAssembly.compile(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchCompileWasm(filePath) {
|
||||||
|
return fetchResource(filePath).then(function(response) {
|
||||||
|
if (typeof WebAssembly.compileStreaming !== "undefined") {
|
||||||
|
self.loaderSubState = "Downloading/Compiling";
|
||||||
|
setStatus("Loading");
|
||||||
|
return WebAssembly.compileStreaming(response).catch(function(error) {
|
||||||
|
// compileStreaming may/will fail if the server does not set the correct
|
||||||
|
// mime type (application/wasm) for the wasm file. Fall back to fetch,
|
||||||
|
// then compile in this case.
|
||||||
|
return fetchThenCompileWasm(response);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fall back to fetch, then compile if compileStreaming is not supported
|
||||||
|
return fetchThenCompileWasm(response);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadEmscriptenModule(applicationName) {
|
||||||
|
|
||||||
|
// Loading in qtloader.js goes through four steps:
|
||||||
|
// 1) Check prerequisites
|
||||||
|
// 2) Download resources
|
||||||
|
// 3) Configure the emscripten Module object
|
||||||
|
// 4) Start the emcripten runtime, after which emscripten takes over
|
||||||
|
|
||||||
|
// Check for Wasm & WebGL support; set error and return before downloading resources if missing
|
||||||
|
if (!webAssemblySupported()) {
|
||||||
|
self.error = "Error: WebAssembly is not supported"
|
||||||
|
setStatus("Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!webGLSupported()) {
|
||||||
|
self.error = "Error: WebGL is not supported"
|
||||||
|
setStatus("Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue waiting if loadEmscriptenModule() is called again
|
||||||
|
if (publicAPI.status == "Loading")
|
||||||
|
return;
|
||||||
|
self.loaderSubState = "Downloading";
|
||||||
|
setStatus("Loading");
|
||||||
|
|
||||||
|
// Fetch emscripten generated javascript runtime
|
||||||
|
var emscriptenModuleSource = undefined
|
||||||
|
var emscriptenModuleSourcePromise = fetchText(applicationName + ".js").then(function(source) {
|
||||||
|
emscriptenModuleSource = source
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch and compile wasm module
|
||||||
|
var wasmModule = undefined;
|
||||||
|
var wasmModulePromise = fetchCompileWasm(applicationName + ".wasm").then(function (module) {
|
||||||
|
wasmModule = module;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for all resources ready
|
||||||
|
Promise.all([emscriptenModuleSourcePromise, wasmModulePromise]).then(function(){
|
||||||
|
completeLoadEmscriptenModule(applicationName, emscriptenModuleSource, wasmModule);
|
||||||
|
}).catch(function(error) {
|
||||||
|
self.error = error;
|
||||||
|
setStatus("Error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function completeLoadEmscriptenModule(applicationName, emscriptenModuleSource, wasmModule) {
|
||||||
|
|
||||||
|
// The wasm binary has been compiled into a module during resource download,
|
||||||
|
// and is ready to be instantiated. Define the instantiateWasm callback which
|
||||||
|
// emscripten will call to create the instance.
|
||||||
|
Module.instantiateWasm = function(imports, successCallback) {
|
||||||
|
WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
|
||||||
|
successCallback(instance, wasmModule);
|
||||||
|
}, function(error) {
|
||||||
|
self.error = error;
|
||||||
|
setStatus("Error");
|
||||||
|
});
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
Module.locateFile = Module.locateFile || function(filename) {
|
||||||
|
return config.path + filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attach status callbacks
|
||||||
|
Module.setStatus = Module.setStatus || function(text) {
|
||||||
|
// Currently the only usable status update from this function
|
||||||
|
// is "Running..."
|
||||||
|
if (text.startsWith("Running"))
|
||||||
|
setStatus("Running");
|
||||||
|
};
|
||||||
|
Module.monitorRunDependencies = Module.monitorRunDependencies || function(left) {
|
||||||
|
// console.log("monitorRunDependencies " + left)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attach standard out/err callbacks.
|
||||||
|
Module.print = Module.print || function(text) {
|
||||||
|
if (config.stdoutEnabled)
|
||||||
|
console.log(text)
|
||||||
|
};
|
||||||
|
Module.printErr = Module.printErr || function(text) {
|
||||||
|
// Filter out OpenGL getProcAddress warnings. Qt tries to resolve
|
||||||
|
// all possible function/extension names at startup which causes
|
||||||
|
// emscripten to spam the console log with warnings.
|
||||||
|
if (text.startsWith !== undefined && text.startsWith("bad name in getProcAddress:"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (config.stderrEnabled)
|
||||||
|
console.log(text)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error handling: set status to "Exited", update crashed and
|
||||||
|
// exitCode according to exit type.
|
||||||
|
// Emscripten will typically call printErr with the error text
|
||||||
|
// as well. Note that emscripten may also throw exceptions from
|
||||||
|
// async callbacks. These should be handled in window.onerror by user code.
|
||||||
|
Module.onAbort = Module.onAbort || function(text) {
|
||||||
|
publicAPI.crashed = true;
|
||||||
|
publicAPI.exitText = text;
|
||||||
|
setStatus("Exited");
|
||||||
|
};
|
||||||
|
Module.quit = Module.quit || function(code, exception) {
|
||||||
|
if (exception.name == "ExitStatus") {
|
||||||
|
// Clean exit with code
|
||||||
|
publicAPI.exitText = undefined
|
||||||
|
publicAPI.exitCode = code;
|
||||||
|
} else {
|
||||||
|
publicAPI.exitText = exception.toString();
|
||||||
|
publicAPI.crashed = true;
|
||||||
|
}
|
||||||
|
setStatus("Exited");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set environment variables
|
||||||
|
Module.preRun = Module.preRun || []
|
||||||
|
Module.preRun.push(function() {
|
||||||
|
for (var [key, value] of Object.entries(config.environment)) {
|
||||||
|
ENV[key.toUpperCase()] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});
|
||||||
|
|
||||||
|
Module.qtCanvasElements = config.canvasElements;
|
||||||
|
|
||||||
|
config.restart = function() {
|
||||||
|
|
||||||
|
// Restart by reloading the page. This will wipe all state which means
|
||||||
|
// reload loops can't be prevented.
|
||||||
|
if (config.restartType == "ReloadPage") {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restart by readling the emscripten app module.
|
||||||
|
++self.restartCount;
|
||||||
|
if (self.restartCount > config.restartLimit) {
|
||||||
|
self.error = "Error: This application has crashed too many times and has been disabled. Reload the page to try again."
|
||||||
|
setStatus("Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadEmscriptenModule(applicationName);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicAPI.exitCode = undefined;
|
||||||
|
publicAPI.exitText = undefined;
|
||||||
|
publicAPI.crashed = false;
|
||||||
|
|
||||||
|
// Finally evaluate the emscripten application script, which will
|
||||||
|
// reference the global Module object created above.
|
||||||
|
self.eval(emscriptenModuleSource); // ES5 indirect global scope eval
|
||||||
|
}
|
||||||
|
|
||||||
|
function setErrorContent() {
|
||||||
|
if (config.containerElements === undefined) {
|
||||||
|
if (config.showError !== undefined)
|
||||||
|
config.showError(self.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (container of config.containerElements) {
|
||||||
|
var errorElement = config.showError(self.error, container);
|
||||||
|
container.appendChild(errorElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLoaderContent() {
|
||||||
|
if (config.containerElements === undefined) {
|
||||||
|
if (config.showLoader !== undefined)
|
||||||
|
config.showLoader(self.loaderSubState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (container of config.containerElements) {
|
||||||
|
var loaderElement = config.showLoader(self.loaderSubState, container);
|
||||||
|
container.appendChild(loaderElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCanvasContent() {
|
||||||
|
if (config.containerElements === undefined) {
|
||||||
|
if (config.showCanvas !== undefined)
|
||||||
|
config.showCanvas();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < config.containerElements.length; ++i) {
|
||||||
|
var container = config.containerElements[i];
|
||||||
|
var canvas = config.canvasElements[i];
|
||||||
|
config.showCanvas(canvas, container);
|
||||||
|
container.appendChild(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setExitContent() {
|
||||||
|
|
||||||
|
// publicAPI.crashed = true;
|
||||||
|
|
||||||
|
if (publicAPI.status != "Exited")
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (config.containerElements === undefined) {
|
||||||
|
if (config.showExit !== undefined)
|
||||||
|
config.showExit(publicAPI.crashed, publicAPI.exitCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!publicAPI.crashed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (container of config.containerElements) {
|
||||||
|
var loaderElement = config.showExit(publicAPI.crashed, publicAPI.exitCode, container);
|
||||||
|
if (loaderElement !== undefined)
|
||||||
|
container.appendChild(loaderElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var committedStatus = undefined;
|
||||||
|
function handleStatusChange() {
|
||||||
|
if (publicAPI.status != "Loading" && committedStatus == publicAPI.status)
|
||||||
|
return;
|
||||||
|
committedStatus = publicAPI.status;
|
||||||
|
|
||||||
|
if (publicAPI.status == "Error") {
|
||||||
|
setErrorContent();
|
||||||
|
} else if (publicAPI.status == "Loading") {
|
||||||
|
setLoaderContent();
|
||||||
|
} else if (publicAPI.status == "Running") {
|
||||||
|
setCanvasContent();
|
||||||
|
} else if (publicAPI.status == "Exited") {
|
||||||
|
if (config.restartMode == "RestartOnExit" ||
|
||||||
|
config.restartMode == "RestartOnCrash" && publicAPI.crashed) {
|
||||||
|
committedStatus = undefined;
|
||||||
|
config.restart();
|
||||||
|
} else {
|
||||||
|
setExitContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send status change notification
|
||||||
|
if (config.statusChanged)
|
||||||
|
config.statusChanged(publicAPI.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatus(status) {
|
||||||
|
if (status != "Loading" && publicAPI.status == status)
|
||||||
|
return;
|
||||||
|
publicAPI.status = status;
|
||||||
|
|
||||||
|
window.setTimeout(function() { handleStatusChange(); }, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCanvasElement(element) {
|
||||||
|
if (publicAPI.status == "Running")
|
||||||
|
Module.qtAddCanvasElement(element);
|
||||||
|
else
|
||||||
|
console.log("Error: addCanvasElement can only be called in the Running state");
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCanvasElement(element) {
|
||||||
|
if (publicAPI.status == "Running")
|
||||||
|
Module.qtRemoveCanvasElement(element);
|
||||||
|
else
|
||||||
|
console.log("Error: removeCanvasElement can only be called in the Running state");
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeCanvasElement(element) {
|
||||||
|
if (publicAPI.status == "Running")
|
||||||
|
Module.qtResizeCanvasElement(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFontDpi(dpi) {
|
||||||
|
Module.qtFontDpi = dpi;
|
||||||
|
if (publicAPI.status == "Running")
|
||||||
|
Module.qtSetFontDpi(dpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fontDpi() {
|
||||||
|
return Module.qtFontDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatus("Created");
|
||||||
|
|
||||||
|
return publicAPI;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="462pt"
|
||||||
|
height="339pt"
|
||||||
|
viewBox="0 0 462 339"
|
||||||
|
version="1.1">
|
||||||
|
<metadata
|
||||||
|
id="metadata20">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<path
|
||||||
|
fill="#41cd52"
|
||||||
|
d=" M 63.50 0.00 L 462.00 0.00 L 462.00 274.79 C 440.60 296.26 419.13 317.66 397.61 339.00 L 0.00 339.00 L 0.00 63.39 C 21.08 42.18 42.34 21.13 63.50 0.00 Z"
|
||||||
|
id="path6" />
|
||||||
|
<path
|
||||||
|
d=" M 122.37 71.33 C 137.50 61.32 156.21 58.79 174.00 58.95 C 190.94 59.16 208.72 62.13 222.76 72.24 C 232.96 79.41 239.59 90.48 244.01 101.93 C 251.16 120.73 253.26 141.03 253.50 161.01 C 253.53 181.13 252.62 201.69 245.96 220.86 C 241.50 233.90 233.01 245.48 221.81 253.52 C 229.87 266.58 238.09 279.54 246.15 292.60 C 236.02 297.27 225.92 301.97 215.78 306.62 C 207.15 292.38 198.56 278.11 189.90 263.89 C 178.19 265.81 166.21 265.66 154.44 264.36 C 140.34 262.67 125.97 258.37 115.09 248.88 C 106.73 241.64 101.48 231.51 97.89 221.21 C 92.01 203.79 90.43 185.25 90.16 166.97 C 90.02 147.21 91.28 127.14 97.24 108.18 C 101.85 93.92 109.48 79.69 122.37 71.33 Z"
|
||||||
|
id="path8"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d=" M 294.13 70.69 C 304.73 70.68 315.33 70.68 325.93 70.69 C 325.96 84.71 325.92 98.72 325.95 112.74 C 339.50 112.76 353.05 112.74 366.60 112.75 C 366.37 121.85 366.12 130.95 365.86 140.05 C 352.32 140.08 338.79 140.04 325.25 140.07 C 325.28 163.05 325.18 186.03 325.30 209.01 C 325.56 215.30 325.42 221.94 328.19 227.75 C 330.21 232.23 335.65 233.38 340.08 233.53 C 348.43 233.50 356.77 233.01 365.12 232.86 C 365.63 241.22 366.12 249.59 366.60 257.95 C 349.99 260.74 332.56 264.08 316.06 258.86 C 309.11 256.80 302.63 252.19 299.81 245.32 C 294.76 233.63 294.35 220.62 294.13 208.07 C 294.11 185.40 294.13 162.74 294.12 140.07 C 286.73 140.05 279.34 140.08 271.95 140.05 C 271.93 130.96 271.93 121.86 271.95 112.76 C 279.34 112.73 286.72 112.77 294.11 112.74 C 294.14 98.72 294.10 84.71 294.13 70.69 Z"
|
||||||
|
id="path10"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
fill="#41cd52"
|
||||||
|
d=" M 160.51 87.70 C 170.80 86.36 181.60 86.72 191.34 90.61 C 199.23 93.73 205.93 99.84 209.47 107.58 C 214.90 119.31 216.98 132.26 218.03 145.05 C 219.17 162.07 219.01 179.25 216.66 196.17 C 215.01 206.24 212.66 216.85 205.84 224.79 C 198.92 232.76 188.25 236.18 178.01 236.98 C 167.21 237.77 155.82 236.98 146.07 231.87 C 140.38 228.84 135.55 224.09 132.73 218.27 C 129.31 211.30 127.43 203.69 126.11 196.07 C 122.13 171.91 121.17 146.91 126.61 122.89 C 128.85 113.83 132.11 104.53 138.73 97.70 C 144.49 91.85 152.51 88.83 160.51 87.70 Z"
|
||||||
|
id="path12" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
|
@ -3,19 +3,46 @@
|
||||||
#include "frmmain.h"
|
#include "frmmain.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
#include <QFontDatabase>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||||
|
QApplication::setAttribute(Qt::AA_Use96Dpi);
|
||||||
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
||||||
//设置高分屏缩放舍入策略
|
|
||||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
QFont font;
|
QFont font;
|
||||||
|
#ifdef Q_OS_WASM
|
||||||
|
QString fontFile = ":/font/DroidSansFallback.ttf";
|
||||||
|
QString fontName = "Droid Sans Fallback";
|
||||||
|
|
||||||
|
//判断图形字体是否存在,不存在则加入
|
||||||
|
QFontDatabase fontDb;
|
||||||
|
if (!fontDb.families().contains(fontName)) {
|
||||||
|
int fontId = fontDb.addApplicationFont(fontFile);
|
||||||
|
QStringList listName = fontDb.applicationFontFamilies(fontId);
|
||||||
|
if (listName.count() == 0) {
|
||||||
|
qDebug() << QString("load %1 error").arg(fontName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//再次判断是否包含字体名称防止加载失败
|
||||||
|
if (fontDb.families().contains(fontName)) {
|
||||||
|
font = QFont(fontName);
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
|
||||||
|
font.setHintingPreference(QFont::PreferNoHinting);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
font.setFamily("Microsoft Yahei");
|
font.setFamily("Microsoft Yahei");
|
||||||
font.setPixelSize(13);
|
font.setPixelSize(13);
|
||||||
|
#endif
|
||||||
a.setFont(font);
|
a.setFont(font);
|
||||||
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||||
|
|
|
@ -6,11 +6,14 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||||
|
QApplication::setAttribute(Qt::AA_Use96Dpi);
|
||||||
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
||||||
//设置高分屏缩放舍入策略
|
|
||||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QApplication a(argc, argv);
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setFamily("Microsoft Yahei");
|
font.setFamily("Microsoft Yahei");
|
||||||
font.setPixelSize(13);
|
font.setPixelSize(13);
|
||||||
|
|
|
@ -6,9 +6,13 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||||
|
QApplication::setAttribute(Qt::AA_Use96Dpi);
|
||||||
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setFamily("Microsoft Yahei");
|
font.setFamily("Microsoft Yahei");
|
||||||
|
|
|
@ -8,9 +8,13 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||||
|
QApplication::setAttribute(Qt::AA_Use96Dpi);
|
||||||
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setFamily("Microsoft Yahei");
|
font.setFamily("Microsoft Yahei");
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||||
|
QApplication::setAttribute(Qt::AA_Use96Dpi);
|
||||||
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
||||||
//设置高分屏缩放舍入策略
|
|
||||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setFamily("Microsoft Yahei");
|
font.setFamily("Microsoft Yahei");
|
||||||
|
|
Loading…
Reference in New Issue