Calling c++ object functions through QWebChannel
-
I made canvas.html like this: There are four buttons here. Each of these buttons triggers an event, and we want to connect this to the canvasViewer object's method and event. But it doesn't work.
js: Uncaught TypeError: wpubEditor.buttonClicked is not a functionThe following code is part of canvas.html.
<body> <div id="wrapper"> <canvas id="myCanvas"></canvas> <div class="gradient-effect"></div> <div class="bottomControl"> <div class="controlWrapper"> <div class="screen-controller left"></div> <div class="screen-controller center"> <button class="ctnBtn" data-action="begin">Begin</button> <button class="ctnBtn" data-action="prev">Previous</button> <button class="ctnBtn" data-action="next">Next</button> <button class="ctnBtn" data-action="end">End</button> <div id="result"></div> </div> </div> </div> </body> <script src="qrc:///qtwebchannel/qwebchannel.js"></script> <script> if (typeof QWebChannel !== 'undefined') { new QWebChannel(qt.webChannelTransport, function (channel) { var canvasViewer = channel.objects.canvasViewer; console.error('canvasViewer:', canvasViewer); var buttons = document.getElementsByClassName("ctnBtn"); for (var i = 0; i < buttons.length; i++) { buttons[i].addEventListener("click", function () { var action = this.getAttribute("data-action"); canvasViewer.buttonClicked(action); }); } var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); context.drawImage(wpubEditor.imageObject, 0, 0); }); } else { console.error("QWebChannel is not defined. Make sure qwebchannel.js is properly loaded."); } canvas.addEventListener('mouseenter', function() { gradientEffect.style.opacity = '0'; }); canvas.addEventListener('mouseleave', function() { gradientEffect.style.opacity = '0.5'; }); </script>The following code is part of htmlViewer object
#include <QWebEngineView> #include <QWebChannel> .... class canvasViewer : public QMainWindow { Q_OBJECT .... public: canvasViewer(QWidget *parent = nullptr); ~canvasViewer(); private slots: void buttonClicked(const QString& action); private: QWebEngineView *webView; QWebChannel *channel; } // .cpp canvasViewer::canvasViewer(QWidget *parent) : QMainWindow(parent) ... , webView(nullptr) , channel(nullptr) { ... ui->setupUi(this); webView = new QWebEngineView(this); setCentralWidget(webView); QString htmlPath = QFileInfo(__FILE__).dir().absolutePath() + "/canvas.html"; QFile file(htmlPath); if (file.exists()) { webView->load(QUrl::fromLocalFile(htmlPath)); } else { qDebug() << "Failed to load canvas.html. File not found."; } channel = new QWebChannel(webView->page()); webView->page()->setWebChannel(channel); channel->registerObject("canvasViewer", this); } .... void canvasViewer::buttonClicked(const QString& action) { if (action == "begin") { qDebug() << "begin"; } else if (action == "prev") { qDebug() << "prev"; } else if (action == "next") { qDebug() << "next"; } else if (action == "end") { qDebug() << "end"; } }How can I fix this to solve it?
-
I made canvas.html like this: There are four buttons here. Each of these buttons triggers an event, and we want to connect this to the canvasViewer object's method and event. But it doesn't work.
js: Uncaught TypeError: wpubEditor.buttonClicked is not a functionThe following code is part of canvas.html.
<body> <div id="wrapper"> <canvas id="myCanvas"></canvas> <div class="gradient-effect"></div> <div class="bottomControl"> <div class="controlWrapper"> <div class="screen-controller left"></div> <div class="screen-controller center"> <button class="ctnBtn" data-action="begin">Begin</button> <button class="ctnBtn" data-action="prev">Previous</button> <button class="ctnBtn" data-action="next">Next</button> <button class="ctnBtn" data-action="end">End</button> <div id="result"></div> </div> </div> </div> </body> <script src="qrc:///qtwebchannel/qwebchannel.js"></script> <script> if (typeof QWebChannel !== 'undefined') { new QWebChannel(qt.webChannelTransport, function (channel) { var canvasViewer = channel.objects.canvasViewer; console.error('canvasViewer:', canvasViewer); var buttons = document.getElementsByClassName("ctnBtn"); for (var i = 0; i < buttons.length; i++) { buttons[i].addEventListener("click", function () { var action = this.getAttribute("data-action"); canvasViewer.buttonClicked(action); }); } var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); context.drawImage(wpubEditor.imageObject, 0, 0); }); } else { console.error("QWebChannel is not defined. Make sure qwebchannel.js is properly loaded."); } canvas.addEventListener('mouseenter', function() { gradientEffect.style.opacity = '0'; }); canvas.addEventListener('mouseleave', function() { gradientEffect.style.opacity = '0.5'; }); </script>The following code is part of htmlViewer object
#include <QWebEngineView> #include <QWebChannel> .... class canvasViewer : public QMainWindow { Q_OBJECT .... public: canvasViewer(QWidget *parent = nullptr); ~canvasViewer(); private slots: void buttonClicked(const QString& action); private: QWebEngineView *webView; QWebChannel *channel; } // .cpp canvasViewer::canvasViewer(QWidget *parent) : QMainWindow(parent) ... , webView(nullptr) , channel(nullptr) { ... ui->setupUi(this); webView = new QWebEngineView(this); setCentralWidget(webView); QString htmlPath = QFileInfo(__FILE__).dir().absolutePath() + "/canvas.html"; QFile file(htmlPath); if (file.exists()) { webView->load(QUrl::fromLocalFile(htmlPath)); } else { qDebug() << "Failed to load canvas.html. File not found."; } channel = new QWebChannel(webView->page()); webView->page()->setWebChannel(channel); channel->registerObject("canvasViewer", this); } .... void canvasViewer::buttonClicked(const QString& action) { if (action == "begin") { qDebug() << "begin"; } else if (action == "prev") { qDebug() << "prev"; } else if (action == "next") { qDebug() << "next"; } else if (action == "end") { qDebug() << "end"; } }How can I fix this to solve it?
@MyNameIsQt I haven't fully read your code, just to mention that a c++ object function called by webchannel needs to be declared as a slot function.
-
@MyNameIsQt I haven't fully read your code, just to mention that a c++ object function called by webchannel needs to be declared as a slot function.
@Bonnie Oh, I made a really big mistake. I should have done it with public slots, but I made a mistake. thank you Now it works.
public slots: void buttonClicked(const QString& action); -
@Bonnie Oh, I made a really big mistake. I should have done it with public slots, but I made a mistake. thank you Now it works.
public slots: void buttonClicked(const QString& action);@MyNameIsQt How about a public slot?
BTW, where iswpubEditor(in the error message) come from? Cannot see that from your code. -
M MyNameIsQt has marked this topic as solved on
-
M MyNameIsQt has marked this topic as solved on
-
@Bonnie Oh, I made a really big mistake. I should have done it with public slots, but I made a mistake. thank you Now it works.
public slots: void buttonClicked(const QString& action);@MyNameIsQt
I know nothing about WebChannel etc., but since you callcanvasViewer.buttonClicked(action)how can that work if it's aprivateslot? -
@MyNameIsQt
I know nothing about WebChannel etc., but since you callcanvasViewer.buttonClicked(action)how can that work if it's aprivateslot?@JonB I made a stupid mistake