Why can't ie11 load the DLL generated by the qt-5.6/activeqt-hierarchy-example?
-
If you look in the Hiierarchy example, there are already some signals sent from Javascript to the C++ code, for example this line in Javascript:
function createSubWidget( form ) { ParentWidget.createSubWidget( form.nameEdit.value ); }
which arrives to this C++ code in objects.cpp:
void QParentWidget::createSubWidget(const QString &name) { QSubWidget *sw = new QSubWidget(this, name); m_vbox->addWidget(sw); sw->setLabel(name); sw->show(); }
So if you want to implement your own signal in Javascript to a slot in C++ try to copy that example...
-
If you look in the Hiierarchy example, there are already some signals sent from Javascript to the C++ code, for example this line in Javascript:
function createSubWidget( form ) { ParentWidget.createSubWidget( form.nameEdit.value ); }
which arrives to this C++ code in objects.cpp:
void QParentWidget::createSubWidget(const QString &name) { QSubWidget *sw = new QSubWidget(this, name); m_vbox->addWidget(sw); sw->setLabel(name); sw->show(); }
So if you want to implement your own signal in Javascript to a slot in C++ try to copy that example...
@hskoglund said in Why can't ie11 load the DLL generated by the qt-5.6/activeqt-hierarchy-example?:
So if you want to implement your own signal in Javascript to a slot in C++ try to copy that example...
sorry,I want to implement own slot in Javascript to a signal in C++. What to do?
-
Aha, you mean you want the other way around? Start with C++ in Qt, emit a signal from there into IE11, which will then launch some Javascript code?
It's supported by ActiveQt, you just use the normal signals: keyword, let's add a timeout event to the hiearchy example above:
to communicate with the Javascript code you can declare C++ variables using the Q_PROPERTY keyword.
So at the top of objects.h I added a timer timeout variable:... class QParentWidget : public QWidget { Q_OBJECT Q_PROPERTY( int timeout READ timeout WRITE setTimeout ) Q_CLASSINFO("ClassID", "{d574a747-8016-46db-a07c-b2b4854ee75c}"); Q_CLASSINFO("InterfaceID", "{4a30719d-d9c2-4659-9d16-67378209f822}"); Q_CLASSINFO("EventsID", "{4a30719d-d9c2-4659-9d16-67378209f823}"); public: QParentWidget(QWidget *parent = 0); QSize sizeHint() const; int timeout() const { return 0; }; // dummy (not used) signals: void signalFromQt(QString); public slots: void createSubWidget( const QString &name ); QSubWidget *subWidget( const QString &name ); void setTimeout( const int value); // this one we call from Javascript private: QVBoxLayout *vbox; }; ...
then in objects.cpp
I added #include "qtimer.h" and the setTimeout function:... void QParentWidget::setTimeout(const int value) { static int i = 0; QTimer::singleShot(value * 1000,[this] { signalFromQt("Hello no.:" + QString::number(++i)); }); } ...
finally I modifed test.html to this:
<script language="javascript"> function createSubWidget( form ) { ParentWidget.createSubWidget( form.nameEdit.value ); } function renameSubWidget( form ) { var SubWidget = ParentWidget.subWidget( form.nameEdit.value ); if ( !SubWidget ) { alert( "No such widget " + form.nameEdit.value + "!" ); return; } SubWidget.label = form.labelEdit.value; form.nameEdit.value = SubWidget.label; } function setTimeout( form ) { ParentWidget.timeout = form.timerEdit.value; } </script> <p> This widget can have many children! </p> <object ID="ParentWidget" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" CODEBASE="C:\Qt\Examples\Qt-5.7\activeqt\build-hierarchy-Desktop_Qt_5_7_1_MSVC2013_32bit-Release\release\hierarchyax.dll"> [Object not available! Did you forget to build and register the server?] </object><br /> <form> <input type="edit" ID="nameEdit" value="" /> <input type="button" value="Create" onClick="createSubWidget(this.form)" /> <input type="edit" ID="labelEdit" /> <input type="button" value="Rename" onClick="renameSubWidget(this.form)" /> <br /> <input type="edit" ID="timerEdit" value="2" /> <input type="button" value = "set Timeout" onClick="setTimeout(this.form)" /> </form> <script language="javascript"> function ParentWidget::signalFromQt( Message ) { alert ("Got a signal from Qt: " + Message); } </script>
I tossed the setFont() functionality and instead I added the "set Timeout" button. Every time you press it, the QTimer::singleShot will be armed and when it fires it will emit the signalFromQt() which is caught by the Javascript code ParentWidget::signalFromQt()
Edit: note that in the test.html file above, the Javascript code for the function ParentWidget::signalFromQt() is at the end, because it has to be placed after the object ID="ParentWidget".... html code ifor the signal to work and the alert box to be shown. Don't know if this is a bug or a feature :-)
-
Aha, you mean you want the other way around? Start with C++ in Qt, emit a signal from there into IE11, which will then launch some Javascript code?
It's supported by ActiveQt, you just use the normal signals: keyword, let's add a timeout event to the hiearchy example above:
to communicate with the Javascript code you can declare C++ variables using the Q_PROPERTY keyword.
So at the top of objects.h I added a timer timeout variable:... class QParentWidget : public QWidget { Q_OBJECT Q_PROPERTY( int timeout READ timeout WRITE setTimeout ) Q_CLASSINFO("ClassID", "{d574a747-8016-46db-a07c-b2b4854ee75c}"); Q_CLASSINFO("InterfaceID", "{4a30719d-d9c2-4659-9d16-67378209f822}"); Q_CLASSINFO("EventsID", "{4a30719d-d9c2-4659-9d16-67378209f823}"); public: QParentWidget(QWidget *parent = 0); QSize sizeHint() const; int timeout() const { return 0; }; // dummy (not used) signals: void signalFromQt(QString); public slots: void createSubWidget( const QString &name ); QSubWidget *subWidget( const QString &name ); void setTimeout( const int value); // this one we call from Javascript private: QVBoxLayout *vbox; }; ...
then in objects.cpp
I added #include "qtimer.h" and the setTimeout function:... void QParentWidget::setTimeout(const int value) { static int i = 0; QTimer::singleShot(value * 1000,[this] { signalFromQt("Hello no.:" + QString::number(++i)); }); } ...
finally I modifed test.html to this:
<script language="javascript"> function createSubWidget( form ) { ParentWidget.createSubWidget( form.nameEdit.value ); } function renameSubWidget( form ) { var SubWidget = ParentWidget.subWidget( form.nameEdit.value ); if ( !SubWidget ) { alert( "No such widget " + form.nameEdit.value + "!" ); return; } SubWidget.label = form.labelEdit.value; form.nameEdit.value = SubWidget.label; } function setTimeout( form ) { ParentWidget.timeout = form.timerEdit.value; } </script> <p> This widget can have many children! </p> <object ID="ParentWidget" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" CODEBASE="C:\Qt\Examples\Qt-5.7\activeqt\build-hierarchy-Desktop_Qt_5_7_1_MSVC2013_32bit-Release\release\hierarchyax.dll"> [Object not available! Did you forget to build and register the server?] </object><br /> <form> <input type="edit" ID="nameEdit" value="" /> <input type="button" value="Create" onClick="createSubWidget(this.form)" /> <input type="edit" ID="labelEdit" /> <input type="button" value="Rename" onClick="renameSubWidget(this.form)" /> <br /> <input type="edit" ID="timerEdit" value="2" /> <input type="button" value = "set Timeout" onClick="setTimeout(this.form)" /> </form> <script language="javascript"> function ParentWidget::signalFromQt( Message ) { alert ("Got a signal from Qt: " + Message); } </script>
I tossed the setFont() functionality and instead I added the "set Timeout" button. Every time you press it, the QTimer::singleShot will be armed and when it fires it will emit the signalFromQt() which is caught by the Javascript code ParentWidget::signalFromQt()
Edit: note that in the test.html file above, the Javascript code for the function ParentWidget::signalFromQt() is at the end, because it has to be placed after the object ID="ParentWidget".... html code ifor the signal to work and the alert box to be shown. Don't know if this is a bug or a feature :-)
@hskoglund hi~thank you again!
I can receive a signal from qt in javascript now. But there's a problem.
I'm sending a qt setTimeout() signal to change IE11 window size and ActiveQT window size.
What's wrong with the javascript ? Why doesn't it change window size ? the following code.class osgActiveGLQT : public QWidget,public QAxBindable { Q_OBJECT Q_PROPERTY(QString WindowSize READ getWindowSize WRITE setWindowSize) public: osgActiveGLQT(QWidget *parent = 0); QSize sizeHint() const { return QWidget::sizeHint().expandedTo(QSize(100, 100)); } QString getWindowSize() const { return _strWindowSize; } private: //Ui::osgActiveGLQTClass ui; signals: void signalFromQt(QString); public slots: void setWindowSize(const QString &string); void resetWindowSize(const QString &string); public slots: void setTimeout();// this one we call from Javascript private: QString _strWindowSize; bool _isFullScreen; private: QPushButton* _windowSizeButton; }; osgActiveGLQT::osgActiveGLQT(QWidget *parent) : QWidget(parent), _strWindowSize("0,0"), _isFullScreen(false) { if (this->objectName().isEmpty()) this->setObjectName(QStringLiteral("osgActiveGLQTClass")); //this->resize(900, 600); _windowSizeButton = new QPushButton(this); _windowSizeButton->setObjectName(QStringLiteral("windowSizeButton")); _windowSizeButton->setGeometry(QRect(10, 5, 75, 23)); _windowSizeButton->setText(QString::fromLocal8Bit("FullWindow")); connect(_windowSizeButton, SIGNAL(clicked()), this, SLOT(setTimeout())); } void osgActiveGLQT::setWindowSize(const QString &string) { if (!requestPropertyChange("WindowSize")) return; propertyChanged("WindowSize"); _strWindowSize = string; int curIndex = _strWindowSize.indexOf(","); QString wid = _strWindowSize.mid(0, curIndex); QString hei = _strWindowSize.mid(curIndex + 1, _strWindowSize.length()); // // //resize(wid.toInt(), hei.toInt()); //update(); } // void osgActiveGLQT::resetWindowSize(const QString &string) { QString strWindowSize = string; int curIndex = strWindowSize.indexOf(","); QString wid = strWindowSize.mid(0, curIndex); QString hei = strWindowSize.mid(curIndex + 1, strWindowSize.length()); // //QMessageBox::information(this, "About QSimpleAX", strWindowSize); //resize(wid.toInt(), hei.toInt()); //update(); } void osgActiveGLQT::setTimeout() { _isFullScreen = !_isFullScreen; if (_isFullScreen) { QRect rct = QApplication::desktop()->availableGeometry(); static int screenWidth = rct.width(); static int screenHeight = rct.height(); QTimer::singleShot(150, [this] { signalFromQt(QString::number(screenWidth) + "," + QString::number(screenHeight)); }); _windowSizeButton->setText(QString::fromLocal8Bit("resetWindow")); } else { int curIndex = _strWindowSize.indexOf(","); QString wid = _strWindowSize.mid(0, curIndex); QString hei = _strWindowSize.mid(curIndex + 1, _strWindowSize.length()); static int screenWidth = wid.toInt(); static int screenHeight = hei.toInt(); QTimer::singleShot(150, [this] { signalFromQt(QString::number(screenWidth) + "," + QString::number(screenHeight)); }); _windowSizeButton->setText(QString::fromLocal8Bit("fullWindow")); } }
<object ID ="osgActiveGLQT" HSPACE="0" VSPACE="0" WIDTH="900" HEIGHT="600" CLASSID="CLSID:B0545661-8607-43BA-A1C2-B43C0A93D976"> <PARAM NAME="WindowSize" VALUE ="900,600" /> [Object not available! Did you forget to build and register the server?] </object> <script language="javascript"> function osgActiveGLQT::signalFromQt( Message ) { //alert ("Got a signal from Qt: " + Message); var curIndex = Message.indexOf(","); // var widthFormQt = Message.substr(0,curIndex); var heightFormQt = Message.substr(curIndex+1, Message.length); // document.getElementById("osgActiveGLQT").style.WIDTH = widthFormQt; document.getElementById("osgActiveGLQT").style.HEIGHT = heightFormQt; var IntwidthFormQt = parseInt(widthFormQt); var IntheightFormQt = parseInt(heightFormQt); window.moveTo(0,0);// window.resizeTo(IntwidthFormQt,IntheightFormQt);// var strWindowSize = "window.resizeTo(" + widthFormQt + "," + heightFormQt + ");"; //osgActiveGLQT.resetWindowSize(Message); } </script>
-
Hmm, looked at your code, C++ seems ok, but the Javascript window resizing stuff I don't know, I'm not that good with Javascript.
If you put back that alert, does it work and show the correct message (width,height)?
If so, then perhaps you need some kind of update/refresh of the window at the end, so make the resizing visible.
-
Hmm, looked at your code, C++ seems ok, but the Javascript window resizing stuff I don't know, I'm not that good with Javascript.
If you put back that alert, does it work and show the correct message (width,height)?
If so, then perhaps you need some kind of update/refresh of the window at the end, so make the resizing visible.
@hskoglund I put back that alert, It shows the correct width and height.
How do I reset width and height styles of osgActiveGLQT in javascript?
<object ID ="osgActiveGLQT" HSPACE="0" VSPACE="0" WIDTH="900" HEIGHT="600" CLASSID="CLSID:B0545661-8607-43BA-A1C2-B43C0A93D976"> <PARAM NAME="WindowSize" VALUE ="900,600" /> [Object not available! Did you forget to build and register the server?] </object>
-
Don't think it's possible to do in Javascript, but what I do know, is that it's pretty easy to change width and height of a QWidget (e.g. setGeometry(), same as in osgActiveGLQT's constructor)
So, easiest would be to implement 2 new slots in your C++ code for the osgActiveGLQT object, for example setHeight() and setWidth().
Then you could call those 2 functions from Javascript, in the same way you call setTimeout() now. -
Don't think it's possible to do in Javascript, but what I do know, is that it's pretty easy to change width and height of a QWidget (e.g. setGeometry(), same as in osgActiveGLQT's constructor)
So, easiest would be to implement 2 new slots in your C++ code for the osgActiveGLQT object, for example setHeight() and setWidth().
Then you could call those 2 functions from Javascript, in the same way you call setTimeout() now.@hskoglund the following code successfully changes window size in javascript.
<script language="javascript"> function ResetWidget() { var e1 = document.getElementById("ParentWidget"); e1.style.width = "1000px"; e1.style.height = "800px"; } </script> <object ID="ParentWidget" WIDTH="900" HEIGHT="600" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" CODEBASE="http://www.qt-project.org/demos/hierarchy.cab"> [Object not available! Did you forget to build and register the server?] </object><br /> <form> <input type="button" value="ResetWidget" onClick="ResetWidget()" /> </form>
-
Don't think it's possible to do in Javascript, but what I do know, is that it's pretty easy to change width and height of a QWidget (e.g. setGeometry(), same as in osgActiveGLQT's constructor)
So, easiest would be to implement 2 new slots in your C++ code for the osgActiveGLQT object, for example setHeight() and setWidth().
Then you could call those 2 functions from Javascript, in the same way you call setTimeout() now.Why is the activeQT window size wrong when i set window size injavascript?
The following screenshots and code
link text<object ID ="osgActiveGLQT" WIDTH = "900" HEIGHT = "600" CLASSID="CLSID:B0545661-8607-43BA-A1C2-B43C0A93D976"> [Object not available! Did you forget to build and register the server?] </object>
#ifndef ActiveQTOSGWidget_H #define ActiveQTOSGWidget_H #include <iostream> #include <QtWidgets/QWidget> #include <QtWidgets/QLayout> #include <QtWidgets/QApplication> #include <QtWidgets/QLCDNumber> #include <QTimer> #include <QMessageBox> #include <osgViewer/CompositeViewer> #include <osgViewer/ViewerEventHandlers> #include <osgGA/MultiTouchTrackballManipulator> #include <osgDB/ReadFile> #include <osgQt/GraphicsWindowQt> #include <osg/PolygonOffset> class ActiveQTOSGWidget : public QWidget { public: ActiveQTOSGWidget(QWidget *parent = 0); public: virtual void paintEvent(QPaintEvent* event) { // Update the camera QPainter paint(this); QPen pen; pen.setColor(QColor(255, 0, 0)); QBrush brush(QColor(255, 0, 0)); paint.setPen(pen); paint.setBrush(brush); int ss = width(); paint.drawRect(0, 0, width(), height()); } }; #endif // OSGVIEW_H
#ifndef OSGACTIVEGLQT_H #define OSGACTIVEGLQT_H #include <iostream> #include <QtWidgets/QWidget> #include <ActiveQt/QAxBindable> #include <QtWidgets/QLayout> #include <QtWidgets/QApplication> #include <QtWidgets/QLCDNumber> #include <QTimer> #include <QApplication> #include <QDesktopWidget> #include <QMessageBox> #include <QPushButton> #include "ui_osgactiveglqt.h" #include "ActiveQTOSGWidget.h" class osgActiveGLQT : public QWidget,public QAxBindable { Q_OBJECT public: osgActiveGLQT(QWidget *parent = 0); private: Ui::osgActiveGLQTClass ui; }; #endif // OSGACTIVEGLQT_H
-
Nice! Resizing is most likely is part of the ActiveX specification, and ActiveQt being of good quality supports it.
Is... there? Why is the activeQT window's size less than QT Createor window's size when I set the size of 'WIDTH' and 'HEIGHT' Properties of ActiveQT Object in javascript?
The following screenshots and code
link text<object ID ="osgActiveGLQT" WIDTH = "900" HEIGHT = "600" CLASSID="CLSID:B0545661-8607-43BA-A1C2-B43C0A93D976"> [Object not available! Did you forget to build and register the server?] </object>
#ifndef ActiveQTOSGWidget_H #define ActiveQTOSGWidget_H #include <iostream> #include <QtWidgets/QWidget> #include <QtWidgets/QLayout> #include <QtWidgets/QApplication> #include <QtWidgets/QLCDNumber> #include <QTimer> #include <QMessageBox> #include <osgViewer/CompositeViewer> #include <osgViewer/ViewerEventHandlers> #include <osgGA/MultiTouchTrackballManipulator> #include <osgDB/ReadFile> #include <osgQt/GraphicsWindowQt> #include <osg/PolygonOffset> class ActiveQTOSGWidget : public QWidget { public: ActiveQTOSGWidget(QWidget *parent = 0); public: virtual void paintEvent(QPaintEvent* event) { // Update the camera QPainter paint(this); QPen pen; pen.setColor(QColor(255, 0, 0)); QBrush brush(QColor(255, 0, 0)); paint.setPen(pen); paint.setBrush(brush); int ss = width(); paint.drawRect(0, 0, width(), height()); } }; #endif // OSGVIEW_H
#ifndef OSGACTIVEGLQT_H #define OSGACTIVEGLQT_H #include <iostream> #include <QtWidgets/QWidget> #include <ActiveQt/QAxBindable> #include <QtWidgets/QLayout> #include <QtWidgets/QApplication> #include <QtWidgets/QLCDNumber> #include <QTimer> #include <QApplication> #include <QDesktopWidget> #include <QMessageBox> #include <QPushButton> #include "ui_osgactiveglqt.h" #include "ActiveQTOSGWidget.h" class osgActiveGLQT : public QWidget,public QAxBindable { Q_OBJECT public: osgActiveGLQT(QWidget *parent = 0); private: Ui::osgActiveGLQTClass ui; }; #endif // OSGACTIVEGLQT_H
-
Hmm it works for me, I tried with the hierarchyax sample and when I set WIDTH and HEIGHT in test.html:
.. <p> This widget can have many children! </p> <object ID="ParentWidget" WIDTH = "900" HEIGHT = "600" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" [Object not available! Did you forget to build and register the server?] </object><br /> ...
the ActiveQt window is set to 900x600:
-
Hmm it works for me, I tried with the hierarchyax sample and when I set WIDTH and HEIGHT in test.html:
.. <p> This widget can have many children! </p> <object ID="ParentWidget" WIDTH = "900" HEIGHT = "600" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" [Object not available! Did you forget to build and register the server?] </object><br /> ...
the ActiveQt window is set to 900x600:
@hskoglund
oh~~ How to get the widget window from HWND in Qt5?The following QT4 code
QWidget *myWidget; HWND hwnd; myWidget=QWidget::find(hwnd);
-
In Qt5 I think you have to step through all the QWidgets and look for a HWND match, like this:
QWidget *myWidget = nullptr; HWND hwnd; for (auto w : findChildren<QWidget*>()) if (hwnd == (HWND) w->winId()) myWidget = w;
-
Thank you very much.
How does the following lambda qt5 code translate into a normal slot for the singleshot in QT4?
QTimer::singleShot(value * 1000,[this] { signalFromQt("Hello no.:" + QString::number(++i)); });
-
@mirro
Qt4 does not support lambdas as far as i know as it must use the new connect syntax that came in Qt5.
So in Qt4 you have to use a normal slot for the singleshot. -
How does the following lambda qt5 code translate into a normal slot for the singleshot in QT4?
[this] { signalFromQt("Hello no.:" + QString::number(++i)); } -
In Qt5 I think you have to step through all the QWidgets and look for a HWND match, like this:
QWidget *myWidget = nullptr; HWND hwnd; for (auto w : findChildren<QWidget*>()) if (hwnd == (HWND) w->winId()) myWidget = w;
@hskoglund
Start with C++ in Qt, emit a signal from there into IE11,Can it be implemented in QT4?QTimer::singleShot(value * 1000,[this] { signalFromQt("Hello no.:" + QString::number(++i)); });
-
@hskoglund
Start with C++ in Qt, emit a signal from there into IE11,Can it be implemented in QT4?QTimer::singleShot(value * 1000,[this] { signalFromQt("Hello no.:" + QString::number(++i)); });