How to emit signal to a PyQtWebkitView javascript from the Application? - javascript

I'm looking to emit a signal from inside my main window to my WebView.
This one would contain javascript to receive an event, load and insert some html content in it.
I've found this documentation http://developer.nokia.com/community/wiki/Connecting_to_a_QObjects_signal_with_JavaScript_slot_in_Qt_WebKit which explains how to insert the Javascript part. But I don't understand where and how it is connected to the application and therefore how I could do it.
I'm not posting any code since the overall environment is pretty complex, I'm just looking to start a task from the webview with a '<|input type='button'>' which result is too long to compute and display instantly.
I would like to put some loading content waiting to receive the actual one and then pop it up.

This is a very good question, I got stuck on it some time! I will show you an example of two way communication: from python to javascript and vice-versa, hope it helps:
import PyQt4.QtGui as gui, PyQt4.QtWebKit as web, PyQt4.QtCore as core
class MyMainWindow(gui.QMainWindow):
proccessFinished = core.pyqtSignal()
def __init__(self, parent=None):
super(MyMainWindow,self).__init__()
self.wv = web.QWebView()
self.setCentralWidget(self.wv)
#pass this main window to javascrip
self.wv.page().mainFrame().addToJavaScriptWindowObject("mw", self)
self.wv.setHtml("""
<html>
<head>
<script language="JavaScript">
function p() {
document.write('Process Finished')
}
mw.proccessFinished.connect(p)
</script>
</head>
<body>
<h1>It works</h1>
<input type=button value=click onClick=mw.doIt()></input>
</body>
</html>
""")
#core.pyqtSlot()
def doIt(self):
print('running a long process...')
print('of course it should be on a thread...')
print('and the signal should be emmited from there...')
self.proccessFinished.emit()
app = gui.QApplication([])
mw = MyMainWindow()
mw.show()
app.exec_()

Related

How to use mailerlite popups in a Next.js application

I'm integrating a mailerlite popup for a client's next.js project, and I'm having a difficult time converting the JavaScript snippets into the jsx required to make the popups function properly. On first load it seems to work just fine, but on relaod I'm getting the following error.
window is not defined
I've encountered the issue while dealing with DOM manipulation, but in this case, judging from the code in the snippet, I need the window object.
Install the following snippet of Javascript on every page of your website right before the closing tag.You only need to add this snippet once, even if you plan to have a few different webforms.
<!-- MailerLite Universal -->
<script>
(function(m,a,i,l,e,r){ m['MailerLiteObject']=e;function f(){
var c={ a:arguments,q:[]};var r=this.push(c);return "number"!=typeof r?r:f.bind(c.q);}
f.q=f.q||[];m[e]=m[e]||f.bind(f.q);m[e].q=m[e].q||f.q;r=a.createElement(i);
var _=a.getElementsByTagName(i)[0];r.async=1;r.src=l+'?v'+(~~(new Date().getTime()/1000000));
_.parentNode.insertBefore(r,_);})(window, document, 'script', 'https://static.mailerlite.com/js/universal.js', 'ml');
var ml_account = ml('accounts', '912433', 'd5p1f7l9g0', 'load');
</script>
<!-- End MailerLite Universal -->
I've placed this code in my Layout wrapper. As previously stated, it works fine on first load, but as soon as the user navigates to a new page above error shows up.
PS I found an old question regarding this topic here, but it's old and not quite relevant to my situation. I need to figure out how to convert the above snippet for nextjs. Any help at all would be appreciated.
This approach treats the MailerLite universal tag as its own <script> hosted on your site's domain.
Add a NextJS custom document.
Create a JavaScript file containing the MailerLite universal tag code in ./public. I put mine in ./public/scripts/ml.js.
Add a <script> tag loading #2 in your custom _document.js file:
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head>
<script async src="/scripts/ml.js"></script>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
Everything worked as intended from there! (Caveat: I'm only using embedded forms).

How to resolve type name conflict from two separate Javascript libraries?

Let me start by saying that I'm primarily a C# programmer who only extremely rarely ventures into JavaScript.
I can write myself some JS code as long as its mostly plain. I can handle jQuery and the odd self-sufficient 3rd-party library, but couldn't code myself out of a wet paper bag when React, Angular, Bootstrap and others enter the scene. I'm also not used to using npm or any other similar package manager.
It was never really my job nor interest, so I never went there. Whenever I code some JS, I reference the required JS files in my <script> tags and then use them as directly as possible.
I'm currently creating a very simple proof of concept web app which will have its client parts rebuilt by competent people sooner or later. But in the mean time I have to provide the bare-bones functionality that will serve as a rough guideline for the next team to take over, whenever that might be.
I've picked two libraries that each seem easy to use and get the job done, when used separately. But when I try to use them together on the same page, I run into a problem: they both use the same name for their main type, and I can't seem to disambiguate between them.
These are the libraries:
JSON Editor
JSON Schema Form Builder
They both declare a type named JSONEditor, which I can use as long as I don't reference both of the libraries at once.
So far I've tried to solve this by using modules and import-ing the type using different names, but it didn't work... I got a bunch of errors in the console about "import not found" and "e is not defined", which makes me think I'm tackling this wrong.
How would I solve this using plain JS if possible?
UPDATE: As suggested, I'm providing a minimal example that demonstrates my use:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Page</title>
<link href="/lib/jsoneditor/jsoneditor.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="container">
<div id="editor" style="width: 300px; height: 200px;"></div>
<div id="form"></div>
</div>
<!--library 1: https://github.com/josdejong/jsoneditor -->
<script src="/lib/jsoneditor/jsoneditor.min.js"></script>
<!--library 2: https://github.com/jdorn/json-editor -->
<script src="/lib/jsonform/jsonform.min.js"></script>
<script>
// Library 1: The JSON code editor.
var editor = new JSONEditor(document.getElementById("editor"), { mode: "code" });
// Library 2: The form builder.
var form = new JSONEditor(document.getElementById("form"), {
ajax: true,
schema: {
$ref: "/api/describe/service/test"
}
});
</script>
</body>
</html>
If I comment out the use of one library (whichever), the other works as expected and the content is displayed at the respective target <div>. But if I try both at once, as shown above, nothing is displayed, and the following error is output to console:
Uncaught TypeError: t is undefined
This happens at the var editor = new JSONEditor line, which makes me think that the type from the second library overwrites the first and causes the problem.
This is understandable to me and isn't the issue per-se. The issue is that I don't know how to import the two JSONEditor types so that they can be referenced separately.
The maintainer of the code editor (JSON Editor, not JSON Schema Form Builder) has addressed and closed an issue about exactly this in the past: https://github.com/josdejong/jsoneditor/issues/270
His recommended solution is something like the following:
<script src="assets/jsoneditor/dist/jsoneditor.min.js"></script>
<script>
var JSONEditorA = JSONEditor;
</script>
<script src="assets/json-editor/dist/jsoneditor.min.js"></script>
<script>
var JSONEditorB = JSONEditor;
</script>
If you must use script tags this is probably the way to go.

How to properly use the LockService in an WebApp deployed by google app scripts?

I am pretty new using google scripts and I am having trouble to understand the properly way to use the LockService on google app scripts, specifically on a webapp. I am currently developing a webapp that is going to be accesed by 25 different users, and they could be maybe accesing on the same period of time, and I want to avoid collisions since there is important information that is going through this script.
I have already read about the LockService and I do understand the concept, it is supposed to prevent from different users to access part or the whole code involving the lock at the same time, right? But I am not sure wether I should implement it on the .gs file or in the html, and how.
Here I leave the main part of my code:
INDEX
<html>
<head>
<meta name="MobileOptimized" content ="width">
</head>
<body>
<form id="customerForm">
<div id="output"></div>
<div id="signature"></div><br>
<img id="rendered" src="" style="display:none">
<input type="button" value="Enviar Firma" onclick="renderSignature();saveImage()"/> </body>
</form>
</html>
<?!= HtmlService.createHtmlOutputFromFile('JavaScript').getContent(); ?>
SCRIPT TO MANAGE GS FILE RETURNS
<script>
//..some code
function saveImage(e){ //This sends the image src to saveImages function
//Assign values to bytes and sign variables
};
google.script.run.withSuccessHandler(onSuccess).compare_tickets(bytes, sign);
google.script.run.withFailureHandler(onFailure).compare_tickets(bytes, sign);
}
function onSuccess(bytes){
google.script.run.saveImage(bytes)
}
function onFailure(error) {
//Throw alert with the error
}
</script>
GS File
function doGet(e){
return HtmlService
.createTemplateFromFile("index")
.evaluate()
.setTitle("Firme aquĆ­ por favor")
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function compare_tickets(bytes, sign){ //first function runned by the index
//some code that reads Some spreadsheets
}
function saveImage(bytes){ //second function runned by the index
var lock = LockService.getScriptLock();
if(lock.tryLock(10000)){
//Do operations/readings/writings on different spreadsheets in case you get the lock
lock.releaseLock();
}
else{
//Tell the user that the system is busy and should retry to send the info
}
}
So the code above shows that I am trying to implement the LockService on the GS file, I have already tried to access from 3 different browsers at the same time but it looks like the 3 of them are actually running the code, and some information is lost, I guess that the lock is not working as I thought it would.
Could you please help me to figure out how to implement the locks?
Thank you so much in advance.

Web: How often does Flask/JS refresh?

I'm trying to get images to display in real-time only on my machine. Think a really basic version of Google Images. The user types in "red hammer" and I show them a picture of red hammer
The problem is the refresh rate. I update the image file to be shown, and when I look it up directly as http://127.0.0.1:6007/static/tree.jpg, that will immediately give me the most recent jpg. And then, strangely enough after I look up something like http://127.0.0.1:6007/static/tree.jpg, the image changes on the initial http://127.0.0.1:6007 !
My setup:
In the static/ directory, tree.jpg:
templates/
show.html
In templates/, show.html:
<!DOCTYPE html>
<html>
<body>
<h1>Text-to-Image Synthesis</h1>
<form method="POST" action="/generator">
<p>Input to Generator: <input type="text" name="input_text"><input type="submit" value="Generate Image"></p>
</form>
<img src="{{url_for('static', filename='tree.jpg')}}" />
</body>
</html>
index.html
and index.html:
<!DOCTYPE html>
<html>
<body>
<h1>Text-to-Image Synthesis</h1>
<form method="POST" action="/generator">
<!-- button -->
<p>Input to Generator: <input type="text" name="input_text"><input type="submit" value="Generate Image"></p>
</form>
</body>
</html>
These two are the same except show.html shows the image on the src=... line.
server.py
#!/usr/bin/env python2.7
import os
from flask import Flask, request, render_template, g, redirect, Response, send_from_directory
tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
app = Flask(__name__, template_folder=tmpl_dir)
#app.route('/')
def index():
return render_template("index.html")
#app.route('/generator', methods=['POST'])
def generator():
# save typed-in text
text = request.form['input_text']
filename = "/home/ubuntu/icml2016/scripts/cub_queries.txt"
with open(filename, "a+") as f:
f.write(text + "\n")
"""
print('start')
subprocess.call('./scripts/demo_cub.sh', shell=True) # change the image in the background
print('end')
"""
return render_template("show.html")
if __name__ == "__main__":
HOST='0.0.0.0'
PORT=6007
app.run(host=HOST, port=PORT)
So now if I've properly given you everything, you should be able to call python3 server.py and see this:
and if you type in "hi" to the box it'll show this:
but when I change tree.jpg to some other image in the background and type in something else, I don't get the instant image update I'm looking for. In other words, that tree won't become the most recent tree :( We want to see Maury's beautiful face on my basic webpage
Your problem relates to http caching - read about the http Expires header. Flask defaults to setting an Expires header of 12 hours. This instructs your web browser that there is no need to ask for tree.jpg again for 12 hours. When your browser needs tree.jpg again it will simply load it from cache, it will not even make a request to your server. Manually entering this tree.jpg URL in your browser overrides this, in doing so you ask your browser to request it again.
You don't appear to have provided the relevant code -- the send_from_directory call serving your static file is where you need to make change.
send_from_directory(directory, filename, cache_timeout=0)
Relevant documentation:
http://flask.pocoo.org/docs/0.12/api/#flask.send_from_directory
http://flask.pocoo.org/docs/0.12/api/#flask.send_file
and send_file_max_age on the same page (the default Expiry)

Javascript loading but not running - rails 3.1

I have in my application layout file an external javascript file witch has several lines of code and at the end runs a function like BooManager.init() no big deal...
the problem is, it is not running the inside code on this javascript file.
this is how i use it:
<script type="text/javascript">
bb_bid = "1615455";
bb_lang = "en-US";
bb_keywords = "iphone4s, apple";
bb_name = "custom";
bb_limit = "8";
bb_format = "bbb";
</script>
<%= javascript_include_tag "http://widgets.boo-box.com/javascripts/embed.js" %>
but it didn`t do anything it was suposed to do...
i`ve tried in simple html file and it works... what am i doing wrong?
NOTE:
the default way in html is this:
<script type="text/javascript">
bb_bid = "1615455";
bb_lang = "en-US";
bb_keywords = "keywords, between, commas";
bb_name = "custom";
bb_limit = "8";
bb_format = "bbb";
</script>
<script type="text/javascript" src="http://static.boo-box.com/javascripts/embed.js"></script>
-- EDIT --
the result generated by rails:
<script type="text/javascript" src="http://static.boo-box.com/javascripts/embed.js"></script>
It's not evaluating the script when loading using the <%= method. I'm not familiar with that syntax, but from the effect, that's what it sounds like. It's treating the script as html rather than code.
jQuery has a script load function that will get a script dynamically from a URL and then eval() it to execute it.
UPDATED WITH SAMPLE CODE
Add jQuery to your app:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
Then use it to load your script:
$.getScript('http://widgets.boo-box.com/javascripts/embed.js');
UPDATE NUMBER 2
I was able to duplicate the problem in this fiddle: http://jsfiddle.net/7x2zT/4/
If what you are trying to accomplish is to get your parameters activated before the script shows the widget - the default one looks like a sidebar, whereas your parameters make it more of a banner, then just make sure you put your parameters above the <script src stuff.
If you must be able to load dynamically, then you're going to have to figure out where the bug lies in the embed code, or if there's some other activation method. That site's documentation doesn't seem to be in English, so I can't help with that.

Categories

Resources