Qt QJSEngine Hallo Welt

Dieses Beispiel basiert auf einem Beispiel aus M. Schlees Buch "Qt Professional Qt Programming" "Turtle Graphics" . Zum besseren Verständnis der Arbeit empfehle ich Ihnen, den Abschnitt "Qt Scripts Scripting Language" zu lesen.

Im Beispiel wird ein einfaches Terminal implementiert, in das Befehle eingegeben werden können. Das Ergebnis der Befehlsausführung wird im selben Terminal angezeigt. Die Benutzeroberfläche wird in QML implementiert.

Erstellen Sie ein Qt Quick Project

Bild

Wir beschreiben die Form. Main.qml-Datei:

import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.0 Window { id: window visible: true width: Screen.width/2 height: Screen.height/2 title: qsTr(" jsEnjine") property string consoleFontFamily: "Consolas" property int fontPixelSize: 14 TextArea { id: textAreaLog anchors.bottom: rectangle.top anchors.bottomMargin: 3 anchors.right: parent.right anchors.rightMargin: 3 anchors.left: parent.left anchors.leftMargin: 3 anchors.top: parent.top anchors.topMargin: 3 readOnly: true } Rectangle { id: rectangle height: 25 anchors.right: parent.right anchors.rightMargin: 3 anchors.left: parent.left anchors.leftMargin: 3 anchors.bottom: parent.bottom anchors.bottomMargin: 3 border.color: "#0c0a0a" TextEdit { id: textEditInput anchors.right: parent.right anchors.rightMargin: 5 anchors.left: parent.left anchors.leftMargin: 5 anchors.bottom: parent.bottom anchors.bottomMargin: 5 anchors.top: parent.top anchors.topMargin: 5 font.pixelSize: fontPixelSize } } } 

Form

Bild

Fügen Sie dem Projekt die AppCore- und Console- Klassen hinzu, und fügen Sie ein wenig main.c hinzu

 #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "appcore.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); AppCore appCore; QQmlApplicationEngine engine; QQmlContext *context = engine.rootContext();//   //      ,  //    //     context->setContextProperty("appCore",&appCore); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if(engine.rootObjects().isEmpty()) return -1; return app.exec(); } 

appcore.h

 #ifndef APPCORE_H #define APPCORE_H #include <QObject> #include <QJSEngine> #include "console.h" class AppCore : public QObject { Q_OBJECT public: explicit AppCore(QObject *parent = nullptr); private: QJSEngine appScriptEngine; Console *userConsole; signals: Q_INVOKABLE void appEndTextArea(const QString& text); Q_INVOKABLE void clearTextArea(); public slots: Q_INVOKABLE void slotEvaluate(const QString& code); }; #endif // APPCORE_H 

appcore.c

 #include "appcore.h" AppCore::AppCore(QObject *parent) : QObject(parent) { userConsole = new Console(this); QJSValue val = appScriptEngine.newQObject(userConsole); appScriptEngine.globalObject().setProperty("console",val); connect(userConsole, SIGNAL(appEndTextArea(QString)),this,SIGNAL(appEndTextArea(QString))); connect(userConsole, SIGNAL(clearTextArea()),this,SIGNAL(clearTextArea())); } void AppCore::slotEvaluate(const QString& code) { QJSValue result = appScriptEngine.evaluate(code); if(result.isError()){ QString er = QString("   %1: %2").arg(result.property("lineNumber").toInt()).arg(result.toString()); emit appEndTextArea(er); } } 

console.h

 #ifndef CONSOLE_H #define CONSOLE_H #include <QObject> class Console : public QObject { Q_OBJECT public: explicit Console(QObject *parent = nullptr); Q_INVOKABLE void log(const QString& message); Q_INVOKABLE void clear(); signals: Q_INVOKABLE void appEndTextArea(const QString& text); Q_INVOKABLE void clearTextArea(); }; #endif // CONSOLE_H 

console.cpp

 #include "console.h" Console::Console(QObject *parent) : QObject(parent) { } void Console::log(const QString& message) { emit appEndTextArea(message); } void Console::clear() { emit clearTextArea(); } 

Im Konstruktor der AppCore- Klasse haben wir QJSEngine eine Instanz der Console- Klasse hinzugefügt und außerdem festgelegt, dass wir über "console" auf die Methoden dieser Klasse zugreifen.

 QJSValue val = appScriptEngine.newQObject(userConsole); appScriptEngine.globalObject().setProperty("console",val); 

Signal appEndTextArea (const QString & text) - Hinzufügen von Text zu textAreaLog in
main.qml .

Signal clearTextArea () - löscht den Textausgabebereich von textAreaLog in main.qml .

Slot slotEvaluate (const QString & code) - Ausführung des in textEditInput in main.qml eingegebenen js- Codes .

Fügen wir Signalhandler in main.qml hinzu :

 Connections{ target: appCore onAppEndTextArea:{ textAreaLog.cursorPosition = textAreaLog.length; textAreaLog.append(text); } onClearTextArea:{ textAreaLog.cursorPosition=0; textAreaLog.text = ""; } } 

Wir fügen dem textEditInput- Signal auch ein Signal hinzu, das den Slot void slotEvaluate (const QString & code) aufruft :

 TextEdit { id: textEditInput anchors.right: parent.right anchors.rightMargin: 5 anchors.left: parent.left anchors.leftMargin: 5 anchors.bottom: parent.bottom anchors.bottomMargin: 5 anchors.top: parent.top anchors.topMargin: 5 font.pixelSize: fontPixelSize Keys.onReturnPressed:{ if(textEditInput.text == "")return; appCore.slotEvaluate(text) clear() } Keys.onEscapePressed: clear() } 

Wenn Sie nun einen Befehl in textEditInput eingeben und die Eingabetaste drücken , wird der Befehl an slotEvaluate im AppCore übergeben . Wenn Sie ESC drücken, wird das Feld textEditInput gelöscht.

Wenn die Anwendung gestartet wird und wir den Befehl console.log ("Hello world") in textEditInput eingeben, sehen wir Hello world im Feld textAreaLog . Wenn Sie einen unbekannten QJSEngine-Befehl eingeben , wird im Terminal ein Fehler angezeigt .

Bild

Daher haben wir eine Anwendung geschrieben, in der wir die Methoden der mit QJSEngine verbundenen Klassen aufrufen und die Ergebnisse dieser Methoden anzeigen können. Jemand wird sagen: "Was hat JS damit zu tun?" Immerhin sind Klassen in C ++ geschrieben? ” , Aber das ist eine andere Geschichte ...

Link Projekt auf Github

Source: https://habr.com/ru/post/de481142/


All Articles