Custom widgets for Scripting use

Hi,

I have made a prototype using DAZ Scripting, containing some DZ chek boxes, DZ buttons, DZ Labels etc to represent some assets from the constant library. When I finished the script I noticed that it became too slow, if I had over 100 assets in my dialog. I thought making a plug in converting my prototype into a C++ class would speed up things. Now I see that althought the plug in is making these widgets they are not parented into my script dialog. They appeared in a different window if I call MyPrototype.show(); I guess that the script wrapper for the DZ Widgets can not load the QWidgets so that is the reason that they are not working together (if I am not wrong).

The hard and maybe not doable solution is to create all the dialog in C++, but I will miss some features of the widgets.

Any other solution is very welcomed ....

 

- Thanks for any ideas ...

Comments

  • danielbui78danielbui78 Posts: 333

    Are you passing your script dialog's Widget object to your plugin so it can use that as the parent Widget when it creates new widgets?  I haven't tried to use a plugin to create widgets in a script before, but I'll try to do an example proof of concept when I have time.

  • MikeDMikeD Posts: 288
    edited July 2021

    No, actualy I didi the vice versa ....

    I created a new class in c++, as a subclass of QGroupBox and I call this class from my script ...
     

    class in header's file:

    //class MDMyWidget {class MDMyWidget : public QGroupBox {	Q_OBJECTpublic:	/// Constructor ////	MDMyWidget (QWidget* parent = 0);	/// Destructor ///	~MDMyWidget ();public slots: // some public functionsprivate:// some private variables	private slots:// some private functions};

     

     

    and in cpp file I added some widgets in this class:

     

     

    MDMyWidget::MDMyWidget(QWidget* parent) :QGroupBox(parent){        //all widgets are set as public items in the header file	wCheckbox = new QCheckBox();	wPixmap = new QPushButton();	wLabel = new QPushButton();	wEdit = new QPushButton();	wSetPixmap = new QPushButton();	wDelete = new QPushButton();	owType = new QLabel();	wNotes = new QPushButton();	wInfos = new QPushButton();	//get the layout	//QLayout *oLayout = this->layout();	QGridLayout* oLayout = new QGridLayout(this);			oLayout->addWidget(wCheckbox, 1, 0);	oLayout->addWidget(wPixmap, 0, 1, 3, 1);	oLayout->addWidget(wLabel, 1, 3);	oLayout->addWidget(wEdit, 1, 4);	oLayout->addWidget(wSetPixmap, 1, 5);	oLayout->addWidget(wDelete, 1, 6);	oLayout->addWidget(owType, 0, 5);	oLayout->addWidget(wNotes, 1, 7);	oLayout->addWidget(wInfos, 1, 8);		//initialize	//some widgets initialization			//this->setLayout(oLayout);	setLayout(oLayout);};

     

     

    In the script I just call the MDMyWidget:

     

     

    //Some dialog wDlg;

    var wMainGroup = new DVGroupBox(wDlg);

    var oMyWidget = new MDMyWidget(wMainGroup );

     

    but it returns that it does not recognize the QGroupBox class (I guess that is caused by the wrapper of the script widgets) ...

    Post edited by MikeD on
  • cridgitcridgit Posts: 1,757
    edited May 2022

    Redacted

    Post edited by cridgit on
  • danielbui78danielbui78 Posts: 333

    MikeD said:

    No, actualy I didi the vice versa ....

    I created a new class in c++, as a subclass of QGroupBox and I call this class from my script ...
     

     

    Thanks for the example code.  It was very helpful.  I have a working proof of concept here for you: https://github.com/danielbui78/dazwidget2script

    I'm assuming that you were using the default macro: 

    DZ_PLUGIN_CLASS_GUID(MDMyWidget, .....);

    but you need to use the custom macro in order to pass arguments in the constructor:

    DZ_PLUGIN_CUSTOM_CLASS_GUID(MDMyWidget, .....);

    Either the SDK is missing some extra macros to make it fully work, or I'm just not aware of it, but if it is missing the extra code, then you'll need to manually define two functions for the custom class macro to work: see pluginmain.cpp (https://github.com/danielbui78/dazwidget2script/blob/main/src/pluginmain.cpp).

    QObject* MDMyWidgetFactory::createInstance(const QVariantList& args) const

    .....

    QObject* MDMyWidgetFactory::createInstance() const

    .....

     

     

    Also, about calling it from your script:

    In the script I just call the MDMyWidget:

     

     

    //Some dialog wDlg;

    var wMainGroup = new DVGroupBox(wDlg);

    var oMyWidget = new MDMyWidget(wMainGroup );

     

    but it returns that it does not recognize the QGroupBox class (I guess that is caused by the wrapper of the script widgets) ...

    I don't know what DVGroupBox is, but if it's a standard Qt or Daz Widget, then you will probably need to use something like:

    var oRealMainGroupWidget = wMainGroup.getWidget();

     

    Here's a screenshot of the proof of concept:

    https://github.com/danielbui78/dazwidget2script/blob/main/screenshot.jpg

     

    Hope this helps.

  • danielbui78danielbui78 Posts: 333
    edited July 2021

    Alternatively, you could instantiate a non-GUI class object from your script, then call public Q_INVOKABLE method of that class object, passing in your script's dialog widget.  This way, you can continue to use the original "DZ_PLUGIN_CLASS_GUID(MDMyWidget, ....);" plugin macro and not bother with the extra class factory functions. 

    To further clarify, the DZ_PLUGIN_CLASS_GUID macro will NOT allow you to pass any arguments to constructors, so you will always get a null parent if you try to directly instantiate a custom widget (that was built using that macro) from script.  However, this only applies to constructors, and Q_INVOKABLE methods will be able to recieve arguments normally... so passing in your parent widget to a non-constructor method of a non-GUI class, and then instantiating from there will work using any of the daz plugin macros.

    Post edited by danielbui78 on
  • MikeDMikeD Posts: 288

    Thanks a lot danielbui78! I will try it!

Sign In or Register to comment.