QWebChannel question: python function not getting value sent from javascript
-
wrote on 18 Jan 2024, 22:17 last edited by htjane
Hi all,
I'm loading an html inside a qwidget and use QWebChannel to establish two-way communication with my mainwindow. The widget was added to stackedwidget.buttonPart1() in html is the callback function of the main window's NextButton, then buttonPart2() is called to load the second part of html elements, which are paired buttons in html, these buttons have callback functions: buttonPair1() and buttonPair2(). When pair number in either of these two functions reach 15, it calculates the result and send it back to python using web_2_pyqt. After trying out someone else's examples, now javascript can get values sent from python, but python cannot get values from javascipt. What did I miss? Any help is appreciated! Simplified code below:
class SharedObj(QWidget): def __init__(self): super().__init__() def pyqt_2_web(self): return "666" def web_2_pyqt(self, result): QMessageBox.information(self, result) value = pyqtProperty(str, fget = pyqt_2_web, fset = web_2_pyqt)
class MyApp(QMainWindow): def __init__(self): super().__init__() self.web_view = QWebEngineView() self.channel = QWebChannel() shared = SharedObj() self.channel.registerObject("tlx", shared) self.web_view.page().setWebChannel(self.channel) self.ui.NextButton.clicked.connect(self.on_next_clicked) def on_next_clicked(self): curr = self.ui.stackedWidget.currentIndex() if curr == 29: self.show_tlx() if curr == 30: self.web_view.page().runJavaScript("buttonPart1();", self.go_to_part2) def go_to_part2(self, clicked): if clicked: self.ui.NextButton.hide() self.web_view.page().runJavaScript("buttonPart2();") def show_tlx(self): url = QUrl(QFileInfo("./nasatlx.html").absoluteFilePath()) self.web_view.load(url) layout = QVBoxLayout() layout.addWidget(self.web_view) widget = QWidget() widget.setLayout(layout) self.ui.stackedWidget.addWidget(widget) self.ui.stackedWidget.setCurrentWidget(widget)
html code:
<html> <head> <title>NASA Task Load Index</title> <script src="qwebchannel.js"></script> <script language="JavaScript" type="text/javascript"> // some initialization //... window.onload = function () { new QWebChannel(qt.webChannelTransport, function (channel) { window.tlx = channel.objects.tlx; }); } function web_2_pyqt(result){ window.tlx.value = result; // is there something wrong about window.tlx? } function pyqt_2_web(msg){ alert(msg); // can receive the msg from python if I call this function in python } // some calculation //functions... function onLoad() { // Get all the scales ready } // Users want to proceed after doing the scales function buttonPart1() { // do something } // User done reading the part 2 instructions function buttonPart2() { // do other things } // They clicked the top pair button function buttonPair1() { pair_num++; if (pair_num >= 15) { calcRating = calcResults(pair_num); web_2_pyqt(calcRating); // pass it to the function to be sent to python } else { //do something } return true; } // They clicked the bottom pair button function buttonPair2() { pair_num++; if (pair_num >= 15) { calcRating = calcResults(pair_num); web_2_pyqt(calcRating); } else { //do something } return true; } // Compute the weights and the final score function calcResults(pair_num) { //calculate } // --> </script> <style> ... </style> </head> <body onLoad="onLoad();"> <div id="div_part1"> Task Questionnaire - Part 1 <br/> <br/> Click on each scale at the point that best indicates your experience of the task <br/> <br/> <div id="scale0"></div> <div id="scale1"></div> <div id="scale2"></div> <div id="scale3"></div> <div id="scale4"></div> <div id="scale5"></div> <br/> </div> <div id="div_part2" style="display:none"> Task Questionnaire - Part 2 <br/> <br/> One each of the following 15 screens, click on the scale title that represents the more important contributor to workload for the task <br/> <br/> </div> <div id="div_part3" style="display:none"> Task Questionnaire - Part 2 <br/> <br/> Click on the factor that represents the more important contributor to workload for the task<br/> <br/> <table> <tr> <td><input class="pair" id="pair1" type="button" value onClick="buttonPair1();"> </td> <td class="def"><div id="pair1_def"></div></td> </tr> <tr> <td align="center"> or </td> <td></td> </tr> <tr> <td><input class="pair" id="pair2" type="button" value onClick="buttonPair2();"></td> <td class="def"><div id="pair2_def"></div></td> </tr> </table> </div> <div id="div_part4" style="display:none"> </div> </body> </html>
-
wrote on 20 Jan 2024, 00:40 last edited by
In the end I moved all html elements into one page and used
self.web_view.page().runJavaScript("result = returnResult();", self.write_tlx_to_csv)
to get the result.
-
1/2