I am using wtf forms with flask to create a form.
I have a file input, which is styled so the default button is not shown.
How can I dynamically change the style after a file is loaded?
Here is my code:
html:
<div class="file-upload my-form">
<img src="https://i.stack.imgur.com/dy62M.png" />
{{ wtf.form_field(form.file)}}
</div>
css:
.my-form input {
margin: 0;
padding: 0;
height: 100%;
opacity: 0;
}
.file-upload {
margin: 40px auto;
border: 1px solid #149174;
border-radius: 100px;
overflow: hidden;
position: relative;
}
.file-upload input {
position: absolute;
width: 300px;
height: 600px;
left: 10px;
top: 20px;
}
.file-upload img {
height: 170px;
width: 170px;
margin: 60px;
}
how can I change the style on input? or show a label with the file name in the worst case...
In the end I dealt with it like this:
function fileCheck() {
var checked = document.getElementById('file')
if (checked.value.length > 0) {
var file_name = checked.value.split(/(\\|\/)/g).pop();
var re = /(?:\.([^.]+))?$/;
var ext = re.exec(file_name)[1];
if (ext != 'pdf') {
document.getElementById('file-container').style.backgroundColor = '#ca2c2c';
document.getElementById("file-desc").innerHTML = "File Loaded with illegal extension: " + ext + " !!";
document.getElementById("final-submit").disabled = true;
}
else {
document.getElementById('file-container').style.backgroundColor = '#149174';
document.getElementById("file-desc").innerHTML = "File Loaded: " + checked.value.split(/(\\|\/)/g).pop();
document.getElementById("final-submit").disabled = false;
}
}
else {
document.getElementById("final-submit").disabled = true;
}
}
And my html looks like this:
<div class="file-upload my-form" id="file-container">
<img src="static/images/upload_icon.png" />
{{ form.file(oninput="fileCheck()") }}
</div>
I have a Django application and I'm using pythonOCC package in it. I have to display the 3D .stl, .stp, .igs files in my template. Normally, when I call the render() function, the following outputs appear on my vscode console and since flask app created by pythonocc instead of django starts running in localhost, my index.html is never rendered. However I need to display the files in a Django template. That's why I have extended the X3DomRenderer Class such as below.
My custom X3DomRenderer class:
class CustomX3DomRenderer(x3dom_renderer.X3DomRenderer):
def render_to_string(self):
self.generate_html_file(self._axes_plane, self._axes_plane_zoom_factor)
return open(self._html_filename, 'r').read()
the HTML codes that returned from render_to_string() function:
<html lang="en">
<head>
<title>pythonOCC 7.4.0 x3dom renderer</title>
<meta name='Author' content='Thomas Paviot - tpaviot#gmail.com'>
<meta name='Keywords' content='WebGl,pythonOCC'>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://x3dom.org/release/x3dom.css">
<script src="https://x3dom.org/release/x3dom.js"></script>
<style>
body {
background: linear-gradient(#ced7de, #808080);
margin: 0px;
overflow: hidden;
}
#pythonocc_rocks {
padding: 5px;
position: absolute;
left: 1%;
bottom: 2%;
height: 38px;
width: 280px;
border-radius: 5px;
border: 2px solid #f7941e;
opacity: 0.7;
font-family: Arial;
background-color: #414042;
color: #ffffff;
font-size: 14px;
opacity: 0.5;
}
#commands {
padding: 5px;
position: absolute;
right: 1%;
top: 2%;
height: 65px;
width: 180px;
border-radius: 5px;
border: 2px solid #f7941e;
opacity: 0.7;
font-family: Arial;
background-color: #414042;
color: #ffffff;
font-size: 14px;
opacity: 0.5;
}
a {
color: #f7941e;
text-decoration: none;
}
a:hover {
color: #ffffff;
}
</style>
</head>
<body>
<x3d id="pythonocc-x3d-scene" style="width:100%;border: none" >
<Scene>
<transform scale="1,1,1">
<transform id="plane_smallaxe_Id" rotation="1 0 0 -1.57079632679">
<inline url="https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/plane.x3d" mapDEFToID="true" namespaceName="plane"></inline>
<inline url="https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/axesSmall.x3d" mapDEFToID="true" namespaceName="axesSmall"></inline>
</transform>
<inline url="https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/axes.x3d" mapDEFToID="true" namespaceName="axes"></inline>
</transform>
<transform id="glbal_scene_rotation_Id" rotation="1 0 0 -1.57079632679"> <Inline onload="fitCamera()" mapDEFToID="true" url="shp6b8ef6d6e61744489de16a6798cfe998.x3d"></Inline>
</transform> </Scene>
</x3d>
<div id="pythonocc_rocks">
pythonocc-7.4.0 x3dom renderer
<br>Check our blog at
<a href=http://www.pythonocc.org>http://www.pythonocc.org</a>
</div>
<div id="commands">
<b>t</b> view/hide shape<br>
<b>r</b> reset view<br>
<b>a</b> show all<br>
<b>u</b> upright<br>
</div>
<script>
var selected_target_color = null;
var current_selected_shape = null;
var current_mat = null;
function fitCamera()
{
var x3dElem = document.getElementById('pythonocc-x3d-scene');
x3dElem.runtime.fitAll();
}
function select(the_shape) // called whenever a shape is clicked
{
// restore color for previous selected shape
if (current_mat) {
current_mat.diffuseColor = selected_target_color;
}
// store the shape for future process
current_selected_shape = the_shape;
console.log(the_shape);
// store color, to be restored later
appear = current_selected_shape.getElementsByTagName("Appearance")[0];
mat = appear.getElementsByTagName("Material")[0];
current_mat = mat;
console.log(mat);
selected_target_color = mat.diffuseColor;
mat.diffuseColor = "1, 0.65, 0";
//console.log(the_shape.getElementsByTagName("Appearance"));//.getAttribute('diffuseColor'));
}
function onDocumentKeyPress(event) {
event.preventDefault();
if (event.key=="t") { // t key
if (current_selected_shape) {
if (current_selected_shape.render == "true") {
current_selected_shape.render = "false";
}
else {
current_selected_shape.render = "true";
}
}
}
}
// add events
document.addEventListener('keypress', onDocumentKeyPress, false);
</script>
</body>
</html>
and here is my view:
def occ_viewer(request):
shape = read_step_file(os.path.join('C:/Users/imgea/desktop/bgtask/bgtask/ThreeDFile', 'splinecage.stp'))
my_renderer = extend_x3dom.CustomX3DomRenderer(path='C:/Users/imgea/desktop/bgtask/bgtask/ThreeDFile')
my_renderer.DisplayShape(shape)
context = {'viewer': my_renderer.render_to_string()}
return render(request, 'success.html', context)
and I have added these HTML codes that I got from render_to_string() function to my template file. The viewer's grid has shown but the 3D object hasn't because of the error below.
Page not found: http://127.0.0.1:8000/file/occview/shp6b8ef6d6e61744489de16a6798cfe998.x3d
The library creates that .x3d file in the same directory with the file that I wanna render to template but I guess the viewer is looking for this .x3d file in the error which I mentioned before even I sent the directory. I couldn't find the cause of this error. Am I missing something?
Thank you!!
To create pdf from html i use easy_pdf with is connected to xhtml2pdf.
Small example:
in view.py
from easy_pdf.rendering import render_to_pdf_response
context = dict({'user_company': 'test'})
template_name = "pdf_template.html"
return render_to_pdf_response(request, template_name, context)
html template:
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<style>
* {
margin: 0 !important;
padding: 0 !important;
}
</style>
</head>
<body>
{{user_company}}
<img src="/static/some_image.png" height="1000" width="1000">
</body>
</html>
Image and all element are placed inside margins:
I have try to change and add some margins options inside side_packages/easy_pdf/templates/easy_pdf/base.html : github link
<style type="text/css">
#page {
// added
margin: 0 !important;
* {
margin: 0 !important;
padding: 0 !important;
}
body {
margin: 0 !important;
padding: 0 !important;
}
#frame {
margin: 0 !important;
}
// changed
size: {{ pagesize|default:"A4" }};
margin-left: 0;
margin-right: 0;
margin-top: 0;
margin-bottom: 0;
#frame header {
-pdf-frame-content: page-header;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
}
#frame footer {
-pdf-frame-content: page-footer;
bottom: 0;
margin-left: 0;
margin-right: 0;
height: 0;
}
}
</style>
But without effect
Question
Where to add or change css options to remove the margins from pdf?
I have found the solution:
you need to add below into you template style:
<style>
#page {
* {
margin: 0;
padding: 0;
}
}
</style>
I'm building a pyqt5 desktop interface where I'm using QWebEngineView to show a html file where I show a Leaflet map. This is working fine.
The next step is to export all features the user added to the map. When I click on "Export Features" on the map nothing happen, but when I open the same html file on my Chromium web browser, the "Export feature" opens the download dialog fine.
PyQt5 script:
self.MainWindow.webMapViewer = QtWebEngineWidgets.QWebEngineView()
self.MainWindow.webPageLayout.addWidget(self.MainWindow.webMapViewer)
self.html_path = os.path.split(os.path.abspath(__file__))[0] + r'/html/test.html'
self.MainWindow.webMapViewer.load(QtCore.QUrl().fromLocalFile(self.html_path))
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<title>FazMaraneyRGB_transparent_mosaic_group1</title>
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.js"></script>
<!-- Leaflet.draw -->
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.js"></script>
<!-- Leaflet Ajax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
<!-- Leaflet Measument -->
<link rel="stylesheet" href="http://ljagis.github.io/leaflet-measure/leaflet-measure.css" />
<script src="http://ljagis.github.io/leaflet-measure/leaflet-measure.min.js"></script>
<style>
body { margin:0; padding:0; }
body, table, tr, td, th, div, h1, h2, input { font-family: "Calibri", "Trebuchet MS", "Ubuntu", Serif; font-size: 11pt; }
#map { position:absolute; top:0; bottom:0; width:100%; } /* full size */
.ctl {
padding: 2px 10px 2px 10px;
background: white;
background: rgba(255,255,255,0.9);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
text-align: right;
}
.title {
font-size: 18pt;
font-weight: bold;
}
.src {
font-size: 10pt;
}
#delete, #export {
position: absolute;
top:100px;
right:10px;
z-index:100;
background:white;
color:black;
padding:6px;
border-radius:4px;
font-family: 'Helvetica Neue';
cursor: pointer;
font-size:12px;
text-decoration:none;
}
#export {
top:130px;
}
</style>
</head>
<body>
<div id='map'></div>
<div id='delete'>Delete Features</div>
<a href='#' id='export'>Export Features</a>
<script>
/* **** Leaflet **** */
// Base layers
// .. OpenStreetMap
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: '© OpenStreetMap contributors'});
// .. White background
var white = L.tileLayer("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEX///+nxBvIAAAAH0lEQVQYGe3BAQ0AAADCIPunfg43YAAAAAAAAAAA5wIhAAAB9aK9BAAAAABJRU5ErkJggg==");
// Overlay layers (TMS)
var lyr1 = L.tileLayer('./tiles/{z}/{x}/{y}.png', {tms: true, maxZoom: 22, opacity: 0.9, attribution: ""});
// Map
var map = L.map('map', {
measureControl: true,
center: [-18.3604868606589, -52.694255477616245],
zoom: 22,
minZoom: 0,
maxZoom: 22,
layers: [osm]
});
lyr1.addTo(map);
//Geojson Layers
var basemaps = {"OpenStreetMap": osm, "Without background": white}
var overlaymaps = {"Layer 1": lyr1}
// Title
var title = L.control();
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl title');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = "FazMaraneyRGB_transparent_mosaic_group1";
};
title.addTo(map);
// Note
var src = 'Generated by Hawkit';
var title = L.control({position: 'bottomleft'});
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl src');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = src;
};
title.addTo(map);
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
}
}).addTo(map);
map.on('draw:created', function(e) {
// Each time a feaute is created, it's added to the over arching feature group
featureGroup.addLayer(e.layer);
});
// on click, clear all layers
document.getElementById('delete').onclick = function(e) {
featureGroup.clearLayers();
}
document.getElementById('export').onclick = function(e) {
// Extract GeoJson from featureGroup
var data = featureGroup.toGeoJSON();
// Stringify the GeoJson
var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data));
// Create export
document.getElementById('export').setAttribute('href', 'data:' + convertedData);
document.getElementById('export').setAttribute('download','data.geojson');
}
// Add base layers
L.control.layers(basemaps, overlaymaps, {collapsed: true}).addTo(map);
// Fit to overlay bounds (SW and NE points with (lat, lon))
map.fitBounds([[-18.36827062251916, -52.6871074784942], [-18.35270287637126, -52.7014028427423]]);
</script>
</body>
</html>
That popup window is generated by the browser, in the case of QWebEngine we must create it. To start, the signal indicating the download must be detected, and this signal is downloadRequested from the QWebEngineProfile. That signal sends us a QWebEngineDownloadItem object that handles the download, in it we create a dialog window with the help of QFileDialog. For this case we will create a custom QWebEnginePage as shown below:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<title>FazMaraneyRGB_transparent_mosaic_group1</title>
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.js"></script>
<!-- Leaflet.draw -->
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.js"></script>
<!-- Leaflet Ajax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
<!-- Leaflet Measument -->
<link rel="stylesheet" href="http://ljagis.github.io/leaflet-measure/leaflet-measure.css" />
<script src="http://ljagis.github.io/leaflet-measure/leaflet-measure.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
body,
table,
tr,
td,
th,
div,
h1,
h2,
input {
font-family: "Calibri", "Trebuchet MS", "Ubuntu", Serif;
font-size: 11pt;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
/* full size */
.ctl {
padding: 2px 10px 2px 10px;
background: white;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
border-radius: 5px;
text-align: right;
}
.title {
font-size: 18pt;
font-weight: bold;
}
.src {
font-size: 10pt;
}
#delete,
#export {
position: absolute;
top: 100px;
right: 10px;
z-index: 100;
background: white;
color: black;
padding: 6px;
border-radius: 4px;
font-family: 'Helvetica Neue';
cursor: pointer;
font-size: 12px;
text-decoration: none;
}
#export {
top: 130px;
}
</style>
</head>
<body>
<div id='map'></div>
<div id='delete'>Delete Features</div>
<a href='#' id='export'>Export Features</a>
<script>
/* **** Leaflet **** */
// Base layers
// .. OpenStreetMap
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
});
// .. White background
var white = L.tileLayer("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEX///+nxBvIAAAAH0lEQVQYGe3BAQ0AAADCIPunfg43YAAAAAAAAAAA5wIhAAAB9aK9BAAAAABJRU5ErkJggg==");
// Overlay layers (TMS)
var lyr1 = L.tileLayer('./tiles/{z}/{x}/{y}.png', {
tms: true,
maxZoom: 22,
opacity: 0.9,
attribution: ""
});
// Map
var map = L.map('map', {
measureControl: true,
center: [-18.3604868606589, -52.694255477616245],
zoom: 22,
minZoom: 0,
maxZoom: 22,
layers: [osm]
});
lyr1.addTo(map);
//Geojson Layers
var basemaps = {
"OpenStreetMap": osm,
"Without background": white
}
var overlaymaps = {
"Layer 1": lyr1
}
// Title
var title = L.control();
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl title');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = "FazMaraneyRGB_transparent_mosaic_group1";
};
title.addTo(map);
// Note
var src = 'Generated by Hawkit';
var title = L.control({
position: 'bottomleft'
});
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl src');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = src;
};
title.addTo(map);
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
}
}).addTo(map);
map.on('draw:created', function(e) {
// Each time a feaute is created, it's added to the over arching feature group
featureGroup.addLayer(e.layer);
});
// on click, clear all layers
document.getElementById('delete').onclick = function(e) {
featureGroup.clearLayers();
}
document.getElementById('export').onclick = function(e) {
// Extract GeoJson from featureGroup
var data = featureGroup.toGeoJSON();
// Stringify the GeoJson
var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data));
// Create export
document.getElementById('export').setAttribute('href', 'data:' + convertedData);
document.getElementById('export').setAttribute('download', 'data.geojson');
}
// Add base layers
L.control.layers(basemaps, overlaymaps, {
collapsed: true
}).addTo(map);
// Fit to overlay bounds (SW and NE points with (lat, lon))
map.fitBounds([
[-18.36827062251916, -52.6871074784942],
[-18.35270287637126, -52.7014028427423]
]);
</script>
</body>
</html>
main.py
from PyQt5 import QtWebEngineWidgets, QtWidgets, QtCore
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
def __init__(self, *args, **kwargs):
QtWebEngineWidgets.QWebEnginePage.__init__(self, *args, **kwargs)
self.profile().downloadRequested.connect(self.on_downloadRequested)
#QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def on_downloadRequested(self, download):
old_path = download.path()
suffix = QtCore.QFileInfo(old_path).suffix()
path, _ = QtWidgets.QFileDialog.getSaveFileName(self.view(), "Save File", old_path, "*."+suffix)
if path:
download.setPath(path)
download.accept()
if __name__ == '__main__':
import sys
sys.argv.append("--remote-debugging-port=8000")
sys.argv.append("--disable-web-security")
app = QtWidgets.QApplication(sys.argv)
view = QtWebEngineWidgets.QWebEngineView()
page = WebEnginePage(view)
view.setPage(page)
path = QtCore.QDir.current().filePath("index.html")
view.load(QtCore.QUrl.fromLocalFile(path))
view.show()
sys.exit(app.exec_())
In your case:
self.MainWindow.webMapViewer = QtWebEngineWidgets.QWebEngineView()
self.MainWindow.webPageLayout.addWidget(self.MainWindow.webMapViewer)
page = WebEnginePage(self.MainWindow.webMapViewer) # create page
self.MainWindow.webMapViewer.setPage(page) # set page
self.html_path = os.path.split(os.path.abspath(__file__))[0] + r'/html/test.html'
self.MainWindow.webMapViewer.load(QtCore.QUrl().fromLocalFile(self.html_path))
Plus:
If you want to set a defined route use the following:
#QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def on_downloadRequested(self, download):
directory = "/path/of/directory"
filename = QtCore.QFileInfo(download.path()).fileName()
download.setPath(QtCore.QDir(directory).filePath(filename))
download.accept()
Good night. This is a question about Brython and any help will be welcome.
I'm looking for a way of moving elements (for example, a div) some pixels to the left (or to the right, top etc.) every time interval (perhaps 200 milliseconds). Can anyone help me?
And it would be great to delete the element once he arrived on the left margin. (:
[update] Here's a starting point. I won't polute it with wrong brython code, follow your creativity ;)
<html><head>
<style>
* { margin: 0; padding: 0; outline: 0; border: 0; }
.block {
display: inline-block;
margin: 1em;
padding: 1em;
background: steelblue;
color: white;
font: 14pt/1.2 georgia,cambria;
border-radius: .2em;
}
</style></head><body>
<div class="block">
Test
</div>
</body></html>
Here is how you can do it :
<html>
<head>
<meta charset="utf-8">
<style>
* { margin: 0; padding: 0; outline: 0; border: 0; }
.block {
display: inline-block;
/*margin: 1em;*/
padding: 1em;
background: steelblue;
color: white;
font: 14pt/1.2 georgia,cambria;
border-radius: .2em;
}
</style>
<script src="/src/brython.js"></script>
<script type="text/python">
import time
elt = doc["moving"]
def move():
elt.style.left = "%spx" %(elt.left+10)
if(elt.left > 500):
time.clear_interval(timer)
del doc["moving"]
timer = time.set_interval(move,200)
</script>
</head>
<body onload="brython(1)">
<div class="block" id="moving" style="position:absolute;top:10;left:20;">
Test
</div>
</body>
</html>
Pretty straightforward, eh ? A few comments :
the DIV element must be set with position = absolute
in the Brython program, you get a reference to the object by doc[object_id] (doc is a built-in name for the document). To delete the object : del doc[object_id]
this object has an attribute left : an integer measuring the distance to the document left border
set_interval and clear_interval are methods added to the built-in module time, they have the same syntax as their Javascript equivalents