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