该示例基于
M. Schlee的书
“ Qt Professional Qt编程”“ Turtle Graphics”中的示例。 为了更好地理解这项工作,我建议您阅读“ Qt脚本脚本语言”部分。
在该示例中,将实现一个简单的终端,可以在其中输入命令。 命令的执行结果将显示在同一终端中。 用户界面将在QML中实现。
创建一个Qt快速项目
我们描述表格。 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 } } }
形式
将
AppCore和
Console类添加到项目中,添加一点
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); } }
控制台 #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(); }
在
AppCore类的构造函数中
,我们向
QJSEngine添加了
Console类的实例,并且还确定我们将通过
“控制台”访问此类的方法。
QJSValue val = appScriptEngine.newQObject(userConsole); appScriptEngine.globalObject().setProperty("console",val);
信号
appEndTextArea(const QString&text) -将文本添加到
textAreamain.qml 。
Signal
clearTextArea() -清除
main.qml中的textAreaLog文本输出
区域 。
Slot
slotEvaluate(const QString&code) -执行在
main.qml中的
textEditInput中输入的js代码。
让我们在
main.qml中添加信号处理程序:
Connections{ target: appCore onAppEndTextArea:{ textAreaLog.cursorPosition = textAreaLog.length; textAreaLog.append(text); } onClearTextArea:{ textAreaLog.cursorPosition=0; textAreaLog.text = ""; } }
我们还向
void slotEvaluate(const QString&code)插槽调用的
textEditInput调用添加了一个信号:
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() }
现在,当您在
textEditInput中键入命令并按
Enter时,该命令将传递到
AppCore中的
slotEvaluate 。 当您按ESC时,将清除
textEditInput字段。
当应用程序启动时,如果我们在
textEditInput中输入console.log(“ Hello world”)
命令,我们将在
textAreaLog字段中看到Hello world。 如果输入未知的
QJSEngine命令 ,则会在终端中
显示错误。
因此,我们编写了一个应用程序,在其中可以调用连接到QJSEngine的类的方法并显示这些方法的结果。 有人会说:
“ JS与它有什么关系?” 毕竟,类是用C ++编写的吗?” ,但这又是另一回事了……
在github上链接项目