In this recipe, we will learn how put our knowledge to use and create a functional login screen using Qt and MySQL.
Learn how to call C++ functions from JavaScript through the following steps:
.pro
) and add the following modules to the project:QT += core gui webengine webenginewidgets
mainwindow.ui
and delete the tool bar, menu bar, and status bar, as we don't need any of these in this example program.stylesheet
property:font: 75 26pt "MS Shell Dlg 2";
test.html
. First, link all the necessary JavaScript and CSS files to the HTML source code, between the <head>
tags:<!DOCTYPE html> <html> <head> <script src="qrc:///qtwebchannel/qwebchannel.js"></script> <script src="js/jquery.min.js"></script> <script src="js/bootstrap.js"></script> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"> <link rel="stylesheet" type="text/css" href="css/font- awesome.css"> </head> <body> </body> </html>
<head>
element, wrapped between the <script>
tags:<script> $(document).ready(function() { new QWebChannel(qt.webChannelTransport, function(channel) { mainWindow = channel.objects.mainWindow; }); $("#login").click(function(e) { e.preventDefault(); var user = $("#username").val(); var pass = $("#password").val(); mainWindow.showLoginInfo(user, pass); }); $("#changeText").click(function(e) { e.preventDefault(); mainWindow.changeQtText("Good bye!"); }); }); </script>
<body>
element:<div class="container-fluid"> <form id="example-form" action="#" class="container-fluid"> <div class="form-group"> <div class="col-md-12"><h3>Call C++ Function from Javascript</h3></div> <div class="col-md-12"><div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <span id="infotext">Click "Login" to send username and password variables to C++.Click "Change Cpp Text" to change the text label on Qt GUI.</span></div></div> <div class="col-md-12"> <label>Username:</label> <input id="username" type="text"><p /> </div> <div class="col-md-12"> <label>Password:</label> <input id="password" type="password"><p /> </div> <div class="col-md-12"> <button id="login" class="btn btn-success" type="button"><i class="fa fa-check"></i> Login</button> <button id="changeText" class="btn btn-primary" type="button"><i class="fa fa-pencil"></i> Change Cpp Text</button> </div> </div> </form> </div>
mainwindow.h
and add the following public functions to the MainWindow
class:public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); Q_INVOKABLE void changeQtText(QString newText); Q_INVOKABLE void showLoginInfo(QString user, QString pass);
mainwindow.cpp
and add the following headers to the top of the source code:#include <QtWebEngineWidgets/QWebEngineView> #include <QtWebChannel/QWebChannel> #include <QMessageBox>
MainWindow
constructor:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "1234"); ui->setupUi(this); QWebEngineView* webview = new QWebEngineView(); ui->verticalLayout->addWidget(webview); QWebChannel* webChannel = new QWebChannel(); webChannel->registerObject("mainWindow", this); webview->page()->setWebChannel(webChannel); webview->page()->load(QUrl("qrc:///html/test.html")); }
changeQtText()
and showLoginInfo()
are called:void MainWindow::changeQtText(QString newText) { ui->label->setText(newText); } void MainWindow::showLoginInfo(QString user, QString pass) { QMessageBox::information(this, "Login info", "Username is " + user + " and password is " + pass); }
In this example, we used two JavaScript libraries, jQuery and Boostrap. We also used an iconic font package called Font Awesome. These third-party add-ons were used to make the HTML user interface more interesting and responsive to different screen resolutions. We also used jQuery to detect the document's ready status, as well as to obtain the values of the input fields. You can download jQuery from https://jquery.com/download, Bootstrap from http://getbootstrap.com/getting-started/#download, and Font Awesome from http://fontawesome.io.
Qt's WebEngine uses a mechanism called Web Channel that enables peer-to-peer communication between the C++ program and the HTML page. The WebEngine module provides a JavaScript library that makes the integration a lot easier. The JavaScript is embedded in your project's resource by default, so you don't need to import it into your project manually. You just have to include it in your HTML page by calling the following:
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
Once you have included qwebchannel.js
, you can initialize the QWebChannel
class and assign the Qt object we registered earlier in C++ to a JavaScript variable.
In C++, it as follows:
QWebChannel* webChannel = new QWebChannel(); webChannel->registerObject("mainWindow", this); webview->page()->setWebChannel(webChannel);
Then in JavaScript, it is as follows:
new QWebChannel(qt.webChannelTransport, function(channel) { mainWindow = channel.objects.mainWindow; });
You may be wondering what this line means:
qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "1234");
Qt's web engine uses the remote debugging method to check for JavaScript errors and other problems. The number 1234
defines the port number you want to use for remote debugging. Once you have enabled remote debugging, you can access the debugging page by opening up a Chromium-based web browser, such as Google Chrome (this will not work in Firefox and other browsers) and typing in http://127.0.0.1:1234
. You will then see a page that look like this:
The first page will display all the HTML pages that are currently running in your program, which in this case is test.html
. Click on the page link and it will take you to another page for inspection. You can use this to check for CSS errors, JavaScript errors, missing files, and so on. Note that you should disable remote debugging once your program is bug-free and ready for deployment. This is because remote debugging takes time to initiate and it will increase your program's startup time.
If you want to call a C++ function from JavaScript, you must place the Q_INVOKABLE
macro in front the function's declaration; otherwise, it will not work:
Q_INVOKABLE void changeQtText(QString newText);
3.144.222.185