calling a function of a plugin from an other plugin [SOLVED]
Hello
is it possible to call a plugin function from an other plugin (2 plugins i'm developping) ? is yes, how can it be ?
thank you
Post edited by darkdesire on
You currently have no notifications.
Hello
is it possible to call a plugin function from an other plugin (2 plugins i'm developping) ? is yes, how can it be ?
thank you
Licensing Agreement | Terms of Service | Privacy Policy | EULA
© 2025 Daz Productions Inc. All Rights Reserved.
Comments
Well, if they have exposed their methods or members to scripting certainly - I don'tknow how the SDK would handle the equivalent. But it would be dependent on the other plug-in, not everything will be exposed and in some cases nothing will (aside from things like seriailisation routines, if needed)
A function belongs to some instance of a class.
Is that class going to be [1] the plugin itself or [2] someting that the plugin creates (ie. a DzAction or a DzPane ...) or [3] is the plugin just going to provide a class that you will need to create an instance of before calling your function, etc...?
[1] see DzPluginMgr and DzPlugin
[2] see DzActionMgr or DzPaneMgr, etc...
[3] create your own manager i.e. how and by who will the created instances/objects be managed? see DzBase
Some things you may want to think about.
Who and what should be able to call your function i.e. everybody via plugin or script, everybody but only by other plugins, only your plugins? Is the function going to create any artifacts and how are those artifacts going to be managed and cleaned up? How many times will it be called and can it be called concurrently?
i have a personal plugin and i need to call a function in an other plugn of mine
thank you
So you have subclassed DzPlugin and used the DZ_CUSTOM_PLUGIN_DEFINITION() to create the other plugin. see SDK documentation "DAZ Studio Plug-in Architecture".
Using DzPluginMgr to find your other plugin and then dynamic casting it to your other plugin class so that you can call the function, is the simple part.
I have never found the need to go down that path myself. I have usually chosen to use the simpler process [2] of subclassing DzAction or DzNode or other managed objects,
That's right. You create a subclass. In it, you declare the function you need as a SLOT (public:) and associate it with a certain signal. When you are in Daz Studio, get a pointer to the object of your first plugin using the corresponding manager (DzActionMgr or DzPaneMgr, etc...) and call its function from your second plugin by sending the mentioned signal. Although in QT it may not even be necessary to get the pointer to the object of the first plugin. It may be enough to simply send the corresponding signal from the second plugin. I don't remember exactly.
Many thank you, i'll try asap.
Wll i've tried DzMainWindow::getPaneMgr(). to obtain the panemgr but i dosen't work, the compilation returns
Erreur C2352 'DzMainWindow::getPaneMgr' : appel non conforme d'une fonction membre non static autolimb C:\xxxxxxxx\perso\daz3d\mes plugind\autolimb\autolimb.cpp 179
found: panemgr = dzApp->getInterface()->getPaneMgr();
So, i've a slot function attach to tmy class ManagerGenesis (first plugin):
public slots:
void GenereAleaPosition();
in my second plugin, i've:
panemgr = dzApp->getInterface()->getPaneMgr();
if (panemgr)
{
dzApp->log("Found a panemgr");
gg= panemgr->findPane("MAnageGenesis");
if (gg)
{
dzApp->log("Found MAnageGenesis");
}
in the log, it writes "found ManageGenesis so ti found it, how call the slot ? connect ?
Many thanks again for your help. no problem it's not urgent.
cheers
Error check - if, for example, DS is running wityhout a UI then getInterface() will return a null and so getPaneMgr() will crash on being called on a null pointer. It is very rarely a good idea to chain things together without validating the returns from the earlier steps.
You need to distinguiksh static methods, which are always available, and dynamic methods, which may not be - again, you need to check vlaidity and not rely on stuff being there without coinfirmation.
There are numerous discussions in this sub forum on using QMetaObject::invokeMethod() to access functions. See https://doc.qt.io/archives/qt-4.8/metaobjects.html for a general explanation.
panemgr->findPane("MAnageGenesis"); //Returns a DzPane* thus gg will be a pointer to just the DzPane part. and thus will only be aware of the standard public DzPane functions. It will not include any of the additional functions you defined in your subclass.
To be able to call any of the additional functions you defined in your subclassing of DzPane, you need to try to cast gg as a pointer to your subclass of DzPane(the DzPane subclass you defined in your firstplugin).
#include "MAnagerGenesis.h" ... void secondPluginFunction() { DzPaneMgr* panemgr = dzApp->getInterface()->getPaneMgr(); if (panemgr) { //If panemgr is valid then dzApp->log("Found a panemgr"); //Write debug info to log file DzPane* gg= panemgr->findPane("MAnageGenesis"); //Using class name, try to find the pane belonging to the first plugin. //NOTE: gg will be a pointer to a DzPane* not a pointer to a MAnageGenesis* if (gg) { //If gg is valid(a MAnageGenesis pane found) then dzApp->log("Found pane"); //Write debug info to log file MAnagerGenesis* ggSubclass = qobject_cast<MAnagerGenesis*>(gg); //see reference Richard provided regarding casting if (ggSubclass) { //if gg is a MAnagerGenesis* (or a subclass of) then dzApp->log("Pane is of type MAnageGenesis"); //Write debug info to log file //Now that you have a valid MAnagerGenesis type pointer // you will be able to call any of the additional public functions you defined in your MAnagerGenesis class. ggSubclass->GenereAleaPosition(); //call GenereAleaPosition function in first plugin } } } }NOTE: As Richard mentioned, dynamic_cast<aType*>(obj) (or qobject_cast) will return 0 if obj is not of type aType*
where as static_cast<aType*>(obj) may return <>0 even if obj is not of type aType.
Thus you can not use if(static_cast<aType*>(obj)) as a check.
If you did not have access to "MAnagerGenesis.h"
then you could use code based on QMetaObject::invokeMethod() instead of the cast based code snipit I added in the above code sample.
If I understand you correctly, you are saying that in the first plugin you connect the function to some globally available event. And to run the function you have the second plugin trigger that global event.
Yes, I have used global application events in some cases. To do this, you first need to include the QEvent class header file in your own class
#include <QtGui/qevent.h>
Then somewhere below the class constructor and destructor, declare the event handling functions
For example
protected:
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent *event);
void closeEvent(QCloseEvent *event); // etc
Finally, in your .cpp class file, describe how these functions will be implemented
Example of a mouse click event handler:
void YouClass::mousePressEvent(QMouseEvent *event)
{
switch (event->button()) //which mouse button was pressed?
{
case Qt::RightButton: // right button was pressed
{
QMessageBox::information
(
dzApp->getDialogParent(), tr("Caught Event"),
"Advanced users press the right mouse button to bring up the context menu", QMessageBox::Close
);
}
break;
case Qt::LeftButton: // it was the left button
{
QMessageBox::information
(
dzApp->getDialogParent(), tr("Caught Event"),
"Stop pressing the left button! You might puncture the monitor screen ;-)", QMessageBox::Close
);
}
break;
}
}
However, this is only suitable for handling global events. It is possible to create a custom event in another plugin. This is described in the examples of using the QEvent class. But unfortunately I do not have time to find and test this now.
Trying with invokeMethod and it works:
mw = dzApp->getInterface();
if (mw)
{
panemgr = mw->getPaneMgr();
if (panemgr)
{
dzApp->log("Found a panemgr");
gg = panemgr->findPane("MAnageGenesis");
if (gg)
{
// MAnageGenesis* ggsubclass;
const QMetaObject* qmo;
// ggsubclass= qobject_cast<MAnageGenesis*>(gg);
qmo = gg->metaObject();
if (qmo)
{
dzApp->log("Found qmo metaobject");
QMetaObject::invokeMethod(gg,"GenereAleaPosition", Qt::DirectConnection);
int ind=qmo->methodCount();
dzApp->log("ind =" + QString::number(ind)+ " methode genealeaposition ;"+QString::number(qmo->indexOfMethod("GenereAleaPosition()"))+" classe : "+qmo->className());
}
}
}
In the log i see trace from other plugin
Excellent! Have you tried calling your function in a real program (Daz Studio), does it work?
Yes, launch DazStudio, the 2 plugins loaded too. Calling a function in plugin1 from the plugin2 and it works.
{
mw = dzApp->getInterface();
if (mw)
{
panemgr = mw->getPaneMgr();
if (panemgr)
{
gg = panemgr->findPane("Plugin2");
if (gg)
{
QMetaObject::invokeMethod(gg, "function1", Qt::DirectConnection);
}
}
}
}
functino1 must be declared in the other plugin as a slot and it works
replace plugin2 with the name of the class of your plugin
Short, clear and understandable code. Excellent solution to the problem. You have transmitted your optimism to me. I will soon go to my own plugin in this jungle that I created in it. I did not have the courage to take apart this logging site after a year. I needed a charge, and I got it. Thank you!
One caveat, DzPaneMgr->findPane only finds panes. So your code will work as long as plugin2 has a DzPane subclass.
i.e. 'replace Plugin2 with the name of the DzPane subclass in your plugin.'
Many thanks for your help
Yes you are right but it's what i needed for instance. I think you can test the plugin type to call the right interface.