Qt QJSEngine Halo dunia

Contoh ini didasarkan pada contoh dari buku M. Schlee "Qt Professional Qt Programming" "Turtle Graphics" . Untuk pemahaman yang lebih baik tentang pekerjaan ini, saya menyarankan Anda untuk membaca bagian "Qt Scripts Scripting Language".

Dalam contoh ini, terminal sederhana akan diimplementasikan ke mana perintah dapat dimasukkan. Hasil dari eksekusi perintah akan ditampilkan di terminal yang sama. Antarmuka pengguna akan diimplementasikan dalam QML.

Buat Proyek Cepat Qt

gambar

Kami menggambarkan formulir. File main.qml:

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 } } } 

Formulir

gambar

Tambahkan kelas AppCore dan Konsol ke proyek, tambahkan sedikit main.c

 #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(); } 

Dalam konstruktor kelas AppCore, kami menambahkan instance kelas Konsol ke QJSEngine , dan kami juga menentukan bahwa kami akan mengakses metode kelas ini melalui "konsol"

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

Signal appEndTextArea (const QString & text) - menambahkan teks ke textAreaLog di
main.qml .

Signal clearTextArea () - kosongkan area output teks textAreaLog di main.qml .

Slot slotEvaluate (const QString & code) - eksekusi kode js dimasukkan dalam textEditInput di main.qml .

Mari tambahkan penangan sinyal di main.qml :

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

Kami juga menambahkan sinyal ke sinyal textEditInput , memanggil slot void slotEvaluate (const QString & code) :

 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() } 

Sekarang ketika Anda mengetik perintah di textEditInput dan tekan Enter, perintah itu akan diteruskan ke slotEvaluate di AppCore . Saat Anda menekan ESC, bidang textEditInput dihapus.

Ketika aplikasi dimulai, jika kita memasukkan perintah console.log ("Hello world") di textEditInput, kita akan melihat Hello world di bidang textAreaLog . Jika Anda memasukkan perintah QJSEngine yang tidak dikenal, kesalahan akan ditampilkan di terminal.

gambar

Jadi, kami menulis sebuah aplikasi di mana kami dapat memanggil metode kelas yang terhubung ke QJSEngine dan menampilkan hasil dari metode ini. Seseorang akan berkata, "Apa hubungannya JS dengan itu?" Lagi pula, kelas ditulis dalam C ++? ” , Tapi itu cerita lain ...

Tautkan proyek di github

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


All Articles