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
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
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();
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.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.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 .
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