Porting Programm with QScriptEngine to QJSEngine
Unsolved
General and Desktop
-
I tryed to get this code running in QT5:
https://github.com/cggos/CPPGUIProgrammingWithQt4/tree/master/chap22/htmleditor
This Example uses QT4 with QScriptEngine.
During runntime a javascript file interacts with a dialog in a ui file.
So i have this ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>StatisticsDialog</class> <widget class="QDialog" name="StatisticsDialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>255</width> <height>163</height> </rect> </property> <property name="windowTitle"> <string>Statistics</string> </property> <layout class="QVBoxLayout"> <item> <widget class="QFrame" name="frame"> <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> <property name="frameShadow"> <enum>QFrame::Raised</enum> </property> <layout class="QGridLayout"> <item row="0" column="0"> <widget class="QLabel" name="charCountLabel"> <property name="text"> <string>Number of characters:</string> </property> </widget> </item> <item row="0" column="1"> <widget class="QLineEdit" name="charCountLineEdit"> <property name="focusPolicy"> <enum>Qt::NoFocus</enum> </property> <property name="text"> <string/> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="readOnly"> <bool>true</bool> </property> </widget> </item> <item row="1" column="0"> <widget class="QLabel" name="wordCountLabel"> <property name="text"> <string>Number of words:</string> </property> </widget> </item> <item row="1" column="1"> <widget class="QLineEdit" name="wordCountLineEdit"> <property name="focusPolicy"> <enum>Qt::NoFocus</enum> </property> <property name="text"> <string/> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="readOnly"> <bool>true</bool> </property> </widget> </item> <item row="2" column="0"> <widget class="QLabel" name="lineCountLabel"> <property name="text"> <string>Number of lines:</string> </property> </widget> </item> <item row="2" column="1"> <widget class="QLineEdit" name="lineCountLineEdit"> <property name="focusPolicy"> <enum>Qt::NoFocus</enum> </property> <property name="text"> <string/> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="readOnly"> <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <layout class="QHBoxLayout"> <item> <spacer> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="closeButton"> <property name="text"> <string>Close</string> </property> <property name="default"> <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </item> </layout> </widget> <resources/> <connections> <connection> <sender>closeButton</sender> <signal>clicked()</signal> <receiver>StatisticsDialog</receiver> <slot>accept()</slot> <hints> <hint type="sourcelabel"> <x>154</x> <y>167</y> </hint> <hint type="destinationlabel"> <x>210</x> <y>178</y> </hint> </hints> </connection> </connections> </ui>
And this javascript code to show number of characters / number of words / number of lines from a QTextEdit
var obj = new Object; obj.text = "&Statistics..."; obj.run = function() { var text = this.textEdit.plainText; this.dialog.frame.charCountLineEdit.text = text.length; this.dialog.frame.wordCountLineEdit.text = this.wordCount(text); this.dialog.frame.lineCountLineEdit.text = this.lineCount(text); this.dialog.exec(); }; obj.wordCount = function(text) { var regExp = new RegExp("\\w+", "g"); var count = 0; while (regExp.exec(text)) ++count; return count; }; obj.lineCount = function(text) { var count = 0; var pos = 0; while ((pos = text.indexOf("\n", pos)) != -1) { ++count; ++pos; } return count + 1; }; return obj;
QtCreator allready warns when i open the .js with "Return statement not allowed outside of Function dialog"
In my mainwindow i handle the script code like this:
void HtmlWindow::createScriptsMenu() { scriptsMenu = menuBar()->addMenu(tr("&Scripts")); auto scriptsDir = directoryOf("scripts"); auto jsFileNames = scriptsDir.entryList(QStringList("*.js"), QDir::Files); for (const auto &jsFileName : jsFileNames) { createScriptAction(scriptsDir.absoluteFilePath(jsFileName)); } scriptsMenu->setEnabled(!scriptsMenu->isEmpty()); } bool HtmlWindow::createScriptAction(const QString &jsFileName) { QFile jsFile(jsFileName); if (!jsFile.open(QIODevice::ReadOnly)) { QMessageBox::warning(this, tr("HTML Editor"), tr("Cannot read file %1:\n%2.") .arg(strippedName(jsFileName)) .arg(jsFile.errorString())); return false; } QTextStream in(&jsFile); in.setCodec("UTF-8"); auto script = in.readAll(); jsFile.close(); QJSValue qsScript = interpreter.evaluate(script); if (qsScript.isError()) { reportScriptError(jsFileName, qsScript); return false; } QString uiFileName = jsFileName; uiFileName.chop(3); uiFileName += ".ui"; QFile uiFile(uiFileName); if (!uiFile.open(QIODevice::ReadOnly)) { QMessageBox::warning(this, tr("HTML Editor"), tr("Cannot read file %1:\n%2.") .arg(strippedName(uiFileName)) .arg(uiFile.errorString())); return false; } QUiLoader loader; QWidget *dialog = loader.load(&uiFile, this); uiFile.close(); if (!dialog) { QMessageBox::warning(this, tr("HTML Editor"), tr("Error loading %1.") .arg(strippedName(uiFileName))); return false; } QJSValue qsDialog = interpreter.newQObject(dialog); qsScript.setProperty("dialog", qsDialog); QJSValue qsTextEdit = interpreter.newQObject(textEdit); qsScript.setProperty("textEdit", qsTextEdit); auto action = new QAction(this); action->setText(qsScript.property("text").toString()); action->setData(QVariant::fromValue(qsScript)); connect(action, &QAction::triggered, this, &HtmlWindow::scriptActionTriggered); scriptsMenu->addAction(action); return true; } void HtmlWindow::reportScriptError(const QString &fileName, const QJSValue &script) { QMessageBox messageBox(this); messageBox.setIcon(QMessageBox::Warning); messageBox.setWindowTitle(tr("HTML Editor")); messageBox.setText(tr("An error occurred while executing the " "script %1.") .arg(strippedName(fileName))); messageBox.setInformativeText( tr("%1.").arg(script.property("name").toString())); messageBox.setDetailedText( tr("Uncaught exception at line %1 : %2") .arg(script.property("lineNumber").toInt()) .arg(script.toString())); messageBox.exec(); }
If I run the app i get the error ""Return statement not allowed outside of Function dialog" as well.
So what to do to get this script code interpreted correctly?