QtScript is not loading QNetwork Module [Windows, 3.7.4]

If you are having problems with QCAD, post here. Please report bugs through our Bug Tracker instead.

Always attach your original DXF or DWG file and mentions your QCAD version and the platform you are on.

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files and screenshots.

Post one question per topic.

Post Reply
Nava2
Junior Member
Posts: 15
Joined: Sun Oct 26, 2014 6:01 pm

QtScript is not loading QNetwork Module [Windows, 3.7.4]

Post by Nava2 » Fri Dec 19, 2014 8:35 pm

First, I would have opened a bug on Flyspray, but the registration seems to be broken and won't accept my authentication code.

The issue: QtScript is not bringing in all of the Qt classes into the global namespace. I'm developing a plugin as a proof of concept and I've been using Qt's networking facilities within QCAD, notably: QNetworkAccessManager, QNetworkReply, and QNetworkResponse. None of these types are available on Windows, but work fine on Linux and Mac. The only difference that might be possible is that I do not have Qt installed on Windows, only QCad.

The Javascript code:
include("./underscore.js"); // see underscorejs.org/, it works without modification and makes code so much nicer to work with

/**
 * @class NetworkFactory allows sending and receiving of network responses on the REST API of the server.
 * @param config Configuration data for the server, this can also be a direct url no port may be specified.
 * @param {QUrl} config.url Server QUrl
 * @constructor
 */
function NetworkFactory(config) {

    if (_.isUndefined(config)) {
        throw new Error("Config must be specified");
    }

    if (_.isString(config)) {
        // we assume it's a url then
        this.url = config;
    }

    this.mgr = new QNetworkAccessManager();

    this.url = config.url;
}

NetworkFactory.prototype = Object.create(Object.prototype);
NetworkFactory.prototype.constructor = NetworkFactory;

/**
 * Creates a new QNetworkRequest with information stored in the factory.
 * @param path
 * @param queryParams
 * @returns {QNetworkRequest}
 */
NetworkFactory.prototype.request = function (path, queryParams) {
    this.request.name = "request";

    if (_.isUndefined(path) || !_.isString(path)) {
        throw new Error("Path is not String: path = " + path);
    }

    var url = new QUrl(this.url);
    url.setPath(path);

    if (!_.isUndefined(queryParams)) {
        if (_.isString(queryParams)) {
            url.setEncodedQuery(Qurl.toPercentEncoding(queryParams));
        } else if (_.isObject(queryParams)) {
            // convert to key-val string
            _.pairs(queryParams).forEach(function (v) { url.addQueryItem(v[0], v[1]); });
        } else {
            // invalid
            debugger;

            throw new Error("Invalid postParams instance = " + queryParams);
        }
    }

    var out = new QNetworkRequest(url);
    out.setRawHeader("content-type", "application/json");

    return out;
};

/**
 *
 * @param {QNetworkReply}   reply Created QNetworkReply
 * @param {Object}          params Same parameter object used in NetworkFactory.get, etc.
 * @param {Function}        [params.onError] Function called on error (`function (QNetworkReply.NetworkError)`)
 * @param {Function}        [params.onSuccess] function called on successful completion (`function (QNetworkReply)`)
 */
NetworkFactory.connectReplySignals = function(reply, params) {
    if (!_.isUndefined(params.onError)) {
        if (_.isFunction(params.onError)) {
            reply['error(QNetworkReply::NetworkError)'].connect(params.onError);
        }
    }

    if (!_.isUndefined(params.onSuccess)) {
        if (_.isFunction(params.onSuccess)) {
            reply.finished.connect(function() {
                params.onSuccess(reply);
            });
        }
    }
};

/**
 *
 * @brief Creates a Network Query
 * @param {Object}      params Parameters for a single network query.
 * @param {String}      params.path Path on the server e.g. `/echo`
 * @param {Object}      [params.body] Content placed into the body of the network request
 * @param {Function}    [params.onSuccess] function called on successful completion (`function (QNetworkReply)`)
 * @param {Function}    [params.onError] Function called on error (`function (QNetworkReply.NetworkError)`)
 * @param {Object}      [params.queryParams] Post-style parameters, if a String will be put directly, if object will be converted
 *                      using key value map: i.e. `key1=val1&key2=val2`
 *
 * @returns {QNetworkReply} Response from QNetworkManager.get()
 */
NetworkFactory.prototype.get = function (params) {

    var req = this.request(params.path, params.queryParams);

    var reply = this.mgr.get(req);

    NetworkFactory.connectReplySignals(reply, params);

    return reply;
};

// code continues with http calls
This code works without issue on Linux and Mac, but windows fails with:
Warning:  RScriptHandlerEcma::RScriptHandlerEcma: script debugger enabled! Not recommended. 
Warning:  RScriptHandlerEcma::eval: script engine exception:  "ReferenceError: Can't find variable: QNetworkAccessManager" 
Warning:  "<anonymous>()@C:/Program Files (x86)/QCAD/scripts/NetworkFactory.js:20" 
Warning:  At least one uncaught exception: 
Warning:  "<anonymous>()@C:/Program Files (x86)/QCAD/scripts/NetworkFactory.js:20" 
Debug:    "<global>() at -1"
Has anyone encountered this issue or had similar problems?
Last edited by Nava2 on Fri Dec 19, 2014 8:54 pm, edited 1 time in total.

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: QtScript is not loading all Qt classes [Windows, 3.7.4]

Post by andrew » Fri Dec 19, 2014 8:42 pm

I can confirm that the QtNetwork module is not available as part of the script API on Windows. The reason being that the script wrappers are not compiling on Windows and since QCAD does not require this module, no one has taken the effort to attempt and fix this to this point.

Nava2
Junior Member
Posts: 15
Joined: Sun Oct 26, 2014 6:01 pm

Re: QtScript is not loading all Qt classes [Windows, 3.7.4]

Post by Nava2 » Fri Dec 19, 2014 8:48 pm

Hmm, so I guess the outcome would be to either:
  • Try to fix it myself
  • Deal without the functionality on Windows and stick to Mac/Linux
I fear it would never be fixed since QtScript has been almost shutdown by digia.

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: QtScript is not loading QNetwork Module [Windows, 3.7.4]

Post by andrew » Fri Dec 19, 2014 9:17 pm

I've had a quick look at the errors. They all seem to be related to SSL. Does your add-on require SSL support?

Nava2
Junior Member
Posts: 15
Joined: Sun Oct 26, 2014 6:01 pm

Re: QtScript is not loading QNetwork Module [Windows, 3.7.4]

Post by Nava2 » Fri Dec 19, 2014 9:31 pm

We're still prototyping, so no. It will in the future.

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: QtScript is not loading QNetwork Module [Windows, 3.7.4]

Post by andrew » Fri Dec 19, 2014 9:47 pm

OK. I can definitely compile the QtNetwork module without SSL support. So this will likely be included in the next QCAD release.

SSL support should basically also work, but requires OpenSSL, which might prompt some legal questions. I'd have to look into this.

Nava2
Junior Member
Posts: 15
Joined: Sun Oct 26, 2014 6:01 pm

Re: QtScript is not loading QNetwork Module [Windows, 3.7.4]

Post by Nava2 » Fri Dec 19, 2014 9:59 pm

That's great! I assume this means that I could also compile my own version with the QNetworking module if I compile QtScript + QNetwork without SSL support?

An assumption, but would dropping a new QtScript DLL solve the issue if I compile Qt from scratch + QCAD from scratch?

Post Reply

Return to “QCAD Troubleshooting and Problems”