Results 1 to 17 of 17

Thread: Using QProcess in QtScript

  1. #1
    Join Date
    Nov 2009
    Posts
    15

    Default Using QProcess in QtScript

    Hello everyone,

    I'm trying to use QProcess from QtScript.

    I've tried a lot of things, but it seems the only way I can make it build is by using Q_SCRIPT_DECLARE_QMETAOBJECT(QProcess, QObject*), and then do:

    Qt Code:
    1. QScriptValue proc = engine.scriptValueFromQMetaObject<QProcess>();
    2. engine.globalObject().setProperty("Process", proc);
    To copy to clipboard, switch view to plain text mode 

    But then I do in the script:

    Qt Code:
    1. var n = new Process();
    2. n.start("someapp");
    To copy to clipboard, switch view to plain text mode 

    And it results in TypeError: Result of expression 'n.start' [undefined] is not a function.

    What am I doing wrong?

    Thanks in advance

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    Easy, Process is a QObject

    You need to tell the script engine that Process is actually a QProcess.

    What you have is correct but not complete. Also use qScriptRegisterMetaType()

  3. #3
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    Can you be more specific?
    It seems I need to specify a toScriptValue and fromScriptValue functions, but I'm not really sure how to do it.

    Thanks!

  4. #4
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    Something in the lines of:

    Qt Code:
    1. class MyObject : public QObject
    2. {
    3. Q_OBJECT
    4. ...
    5. };
    6.  
    7. Q_DECLARE_METATYPE(MyObject*)
    8.  
    9. QScriptValue myObjectToScriptValue(QScriptEngine *engine, MyObject* const &in)
    10. { return engine->newQObject(in); }
    11.  
    12. void myObjectFromScriptValue(const QScriptValue &object, MyObject* &out)
    13. { out = qobject_cast<MyObject*>(object.toQObject()); }
    14.  
    15. ...
    16.  
    17. qScriptRegisterMetaType(&engine, myObjectToScriptValue, myObjectFromScriptValue);
    To copy to clipboard, switch view to plain text mode 

    Edit: changed the code as mentioned on the Qt documentation website
    Last edited by tbscope; 5th November 2010 at 16:36.

  5. #5
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    I had to change a bit the functions since QProcess can't be copied.

    But now I'm having this issue:
    Qt Code:
    1. /usr/include/qt4/QtCore/qmetatype.h: In static member function ‘static int QMetaTypeId2<T>::qt_metatype_id() [with T = QProcess]’:
    2. /usr/include/qt4/QtCore/qmetatype.h:230: instantiated from ‘int qMetaTypeId(T*) [with T = QProcess]’
    3. /usr/include/qt4/QtCore/qmetatype.h:243: instantiated from ‘int qRegisterMetaType(T*) [with T = QProcess]’
    4. /usr/include/qt4/QtScript/qscriptengine.h:402: instantiated from ‘int qScriptRegisterMetaType(QScriptEngine*, QScriptValue (*)(QScriptEngine*, const T&), void (*)(const QScriptValue&, T&), const QScriptValue&, T*) [with T = QProcess]’
    5. mainwindow.cpp:69: instantiated from here
    6. /usr/include/qt4/QtCore/qmetatype.h:169: error: ‘qt_metatype_id’ is not a member of ‘QMetaTypeId<QProcess>’
    To copy to clipboard, switch view to plain text mode 

    Any ideas?

    Thanks again

  6. #6
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    Yes, do not forget Q_DECLARE_METATYPE

  7. #7
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    Right... I thought that was implicit since it's already a QObject...

    But now:
    Qt Code:
    1. /usr/include/qt4/QtCore/qprocess.h: In function ‘void* qMetaTypeConstructHelper(const T*) [with T = QProcess]’:
    2. /usr/include/qt4/QtCore/qmetatype.h:196: instantiated from ‘int qRegisterMetaType(const char*, T*) [with T = QProcess]’
    3. mainwindow.cpp:4: instantiated from here
    4. /usr/include/qt4/QtCore/qprocess.h:224: error: ‘QProcess::QProcess(const QProcess&)’ is private
    5. /usr/include/qt4/QtCore/qmetatype.h:142: error: within this context
    To copy to clipboard, switch view to plain text mode 

    this isn't as easy as it sounded... at least to me...

  8. #8
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    :-)

    This isn't easy :-)

    Wrap your QProcess in a QSharedPointer.
    This whole QScript mess is very complex. On one hand you have to have copy constructors, but on the other hand, they are not allowed.
    You can solve this by using a QSharedPointer

  9. #9
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    I'm going to come out as the stupidest guy in here but... how can I wrap it with an object that isn't a QObject?

  10. #10
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    Note: I didn't compile this, so there might be a syntax error.

    Example:

    Qt Code:
    1. QScriptValue qScriptValueFromProcess(QScriptEngine *engine, const QSharedPointer<QProcess> &object)
    2. {
    3. return engine->newQObject(object.data());
    4. }
    5.  
    6. void qScriptValueToProcess(const QScriptValue & value, QSharedPointer<QProcess> & object)
    7. {
    8. }
    9.  
    10. Q_SCRIPT_DECLARE_QMETAOBJECT(QProcess, QObject*)
    11. Q_DECLARE_METATYPE(QSharedPointer<QProcess>)
    12.  
    13. QScriptValue processValue = m_engine->scriptValueFromQMetaObject<QProcess>();
    14. m_engine->globalObject().setProperty("Process", processValue);
    15.  
    16. qScriptRegisterMetaType(m_engine, qScriptValueFromProcess, qScriptValueToProcess);
    To copy to clipboard, switch view to plain text mode 

    m_engine is a member variable containing a pointer to a script engine.

  11. #11
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    Great, so now it built, but it's the same problem as before, I can declare a variable, assign new Process(), but when I call variable.start("ls") it's the same error...

    Any ideas?

  12. #12
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    Ohh now I remember.

    The functions you want to use need to be defined as a property or a slot :-(
    Try the kill() or terminate() functions, they will work.
    You can write a wrapper, which is just a QProcess subclass defining the functions as slots.

    Sigh... now I remember why it took me a week to get the Qt Creator cpp parser to work in scripts.

  13. #13
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    GREAT!!! You're right...

    At least I have some kind of idea on how to do this... because I'll need to wrap a lot more objects probably

    Thanks a lot tbscope...

  14. #14
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    I just tried it, and this works:

    Note, I created a widget with a plain text edit and a button.

    Header
    Qt Code:
    1. class MyProcess : public QProcess
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. MyProcess(QObject* parent = 0) : QProcess(parent) {}
    7. ~MyProcess() {}
    8.  
    9. public slots:
    10. void startMyProcess(const QString& proc);
    11. };
    12.  
    13. class Widget : public QWidget
    14. {
    15. Q_OBJECT
    16.  
    17. public:
    18. explicit Widget(QWidget *parent = 0);
    19. ~Widget();
    20.  
    21. public slots:
    22. void runScript();
    23.  
    24. private:
    25. Ui::Widget *ui;
    26.  
    27. QScriptEngine *m_engine;
    28. };
    To copy to clipboard, switch view to plain text mode 


    Implementation:
    Qt Code:
    1. QScriptValue qScriptValueFromProcess(QScriptEngine *engine, const QSharedPointer<MyProcess> &object)
    2. {
    3. return engine->newQObject(object.data());
    4. }
    5.  
    6. void qScriptValueToProcess(const QScriptValue &, QSharedPointer<MyProcess> &)
    7. {
    8. }
    9.  
    10. Q_SCRIPT_DECLARE_QMETAOBJECT(MyProcess, QObject*)
    11. Q_DECLARE_METATYPE(QSharedPointer<MyProcess>)
    12.  
    13. void MyProcess::startMyProcess(const QString &proc)
    14. {
    15. start(proc);
    16. }
    17.  
    18. Widget::Widget(QWidget *parent) :
    19. QWidget(parent),
    20. ui(new Ui::Widget),
    21. m_engine(new QScriptEngine)
    22. {
    23. ui->setupUi(this);
    24.  
    25. QScriptValue processValue = m_engine->scriptValueFromQMetaObject<MyProcess>();
    26. m_engine->globalObject().setProperty("Process", processValue);
    27.  
    28. qScriptRegisterMetaType(m_engine, qScriptValueFromProcess, qScriptValueToProcess);
    29.  
    30. connect(ui->buttonRun, SIGNAL(clicked()), this, SLOT(runScript()));
    31. }
    32.  
    33. Widget::~Widget()
    34. {
    35. delete ui;
    36. }
    37.  
    38. void Widget::runScript()
    39. {
    40. QScriptValue resultValue = m_engine->evaluate(ui->textScript->toPlainText(), "test");
    41.  
    42. if(resultValue.isError())
    43. qDebug() << "Error: " << resultValue.toString();
    44.  
    45. }
    To copy to clipboard, switch view to plain text mode 

  15. #15
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    When I try something just like you did I get "QProcess: Destroyed while process is still running"... but with static functions it works... I'm running this on Linux, may be that's the problem, I don't know... I've created a test slot that just prints a string, and it works, so this isn't a problem of calling a non-static member function...

    For now I can do with the static ones, we'll see how it goes with other classes...

    Thanks again for everything!

  16. #16
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Using QProcess in QtScript

    You might want to keep a private pointer to an existing QProcess in the wrapper.
    I did something similar here:
    http://gitorious.org/qt-creator-stat...68de862ba7527b

    And done a bit different:
    http://doc.qt.nokia.com/4.7/script-customclass.html
    Last edited by tbscope; 7th November 2010 at 10:35.

  17. #17
    Join Date
    Nov 2009
    Posts
    15

    Default Re: Using QProcess in QtScript

    Thanks for the links...

    Now, I've got to handle (for now) one type of scripts. What they need to do is a couple of file operations (create some empty dir, check some file for existence, etc... nothing fancy), and then start a new process with certain arguments. So, that's kind of worked out with all that's already discussed, but there's another issue: it'll be good to have each script to set up its own UI elements in a more general dialog from the application.

    I've only worked with non-scripts plugins in qt... and they handle themselves quite differently, obviously. If I were using this kind of plugins, I'd probably just do something like the setupUi function from the qt designer generated files, and have a slot I can call from the main app to start the process that the plugin represents (all the other stuff would be handled from the script itself and the generated UI). So when the app starts, I load every plugin, execute setupUi(some_container), and later on trigger the execute slot; after that the plugin will handle all the UI signals that correspond to it.
    How can I port this idea to a plugin implemented with qtscript?

Similar Threads

  1. Replies: 0
    Last Post: 26th August 2010, 10:44
  2. QtScript
    By lamosca in forum Newbie
    Replies: 2
    Last Post: 20th May 2010, 23:01
  3. Replies: 0
    Last Post: 25th November 2009, 07:46
  4. Please help with QtScript
    By Haccel in forum Qt Programming
    Replies: 0
    Last Post: 16th December 2008, 05:59
  5. QtScript
    By QTInfinity in forum Qt Programming
    Replies: 1
    Last Post: 20th November 2008, 20:10

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.