PDA

View Full Version : How i can access my custom plugin when i loaded a ui file, my program crashed



serjik
3rd May 2011, 18:20
Hello
I design a simple Qt designer custom plugin, i need this plugin for Qt Designer, its ok and it has no problem, i start to design my main program, i want to load a ui file which contains my custom widgets, i use uitools to load this ui file and also with no problem,
but i need to access this custom widgets in ui file after loading, here is a small problem and it's just not work. i attached my custom plugin source and two test projects, what can i do ? any suggestion ? PLEASE!?!


//++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
main.cpp===========

#include <QApplication>
#include <QUiLoader>
#include <QWidget>
#include <QFile>
#include <QMainWindow>
#include <QtGui>

#include "QGLabel.h"//???????????????????

//Qt 4.7.0

int main(int argc, char **argv)
{
Q_INIT_RESOURCE(test);

QApplication app(argc, argv);

QUiLoader loader;
QFile uiFile(":/test.ui");
uiFile.open(QIODevice::ReadOnly);
QWidget *ui = loader.load(&uiFile);
uiFile.close();

ui->show();

//-------------------------------------------------------------------------

//after loading this form i need to access its child widgets
// QGLabel *l1 = qFindChild<QGLabel *>(ui, "g0");

qDebug() << "---------------------";
// qDebug() << l1;//here shoes the pointer is null
qDebug() << "---------------------";

//but when i try to access one of this child custom widgets
//my program crashed
// l1->setText("i can change it");//here crashed

//so i need to make a QList of this custom widgets
//QList<QGLabel *> allQGLabels = ui->findChildren<QGLabel *>();

//PLEASE what can i do??

return app.exec();
}

//++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
test.prj ===========


CONFIG += uitools



RESOURCES += test.qrc

SOURCES += main.cpp

#HEADERS += QGLabel.h


//++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++

high_flyer
4th May 2011, 09:06
does


QStringList strlPaths = loader.pluginPaths ();

includes the path in which your plugin is in?

serjik
4th May 2011, 09:32
Thank you for reply, i copy my custom plugin dll file in designer path and i can make my ui file with Qt-Designer and there is no problem, so my loader in main program can find it and loads my custom plugin and shoes in loaded form its ok and has no problem, i need to access the my custom plugin in loaded form and send/receive data to it same as calculator builder example (here->http://doc.qt.nokia.com/latest/designer-calculatorbuilder.html), in that ui file after loading i can access other Qt's standard widgets but when i try to access my custom widget, its crashed, i really need it, but i dont know what can i do.
i appreciate any suggestion, thanks in advance,
Regards Serjik.

high_flyer
4th May 2011, 09:49
do you get anything with


QList<QGLabel*> lstLabels = ui->findChildren<QGLabel*>();

serjik
5th May 2011, 08:03
Hello high_flyer
i change my *.pro file alittle and main.cpp after compilation i get some errors, i shoe those in main.cpp, but generally, i think i need a correct .pro file and using dll, where or how can i find a little example for this problem?
thanks in advance.

//================================================== ==========
my test.pro file:

QT += core gui

CONFIG += uitools

LIBS += c:/QGLabelPlugin_Release.dll

INCLUDEPATH += C:/ \
C:/TEST/test1

RESOURCES += test.qrc

SOURCES += main.cpp

HEADERS += QGLabel.h

//================================================== ==========
my main.cpp file:


#include <QApplication>
#include <QUiLoader>
#include <QWidget>
#include <QFile>
#include <QMainWindow>
#include <QtGui>

#include "QLabel.h"

#include "QGLabel.h"//???????????????????

//Qt 4.7.0

int main(int argc, char **argv)
{
Q_INIT_RESOURCE(test);

QApplication app(argc, argv);

QUiLoader loader;
QFile uiFile(":/test.ui");
uiFile.open(QIODevice::ReadOnly);
QWidget *ui = loader.load(&uiFile);
uiFile.close();

qDebug() << loader.pluginPaths();
/*
qDebug() shoes (((1))): ("C:/Qt/2010.05/qt/plugins\designer")
<<<this is designer path and >>>
<<<"QGLabelPlugin_Release.dll" is there>>>
qDebug() shoes (((2))): ("C:/TEST/test-build-desktop/release\designer")
also i copied "QGLabelPlugin_Release.dll" to c:/
*/

ui->show();
//after loading this form i need to access its child widgets


//-------------------------------------------------------------------------
//i can access Qt NORMAL widget, here i can change it and its OK
QLabel *normalWidget = qFindChild<QLabel *>(ui, "labelName");
normalWidget->setFont(QFont("Arial", 22, 3, true));
normalWidget->setText("i can change Qt Normal widget...");
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
//now i need to change my custom widget
QGLabel *myCustomWidget = qFindChild<QGLabel *>(ui, "g0");
myCustomWidget->setFont(QFont("Arial", 22, 3, true));
myCustomWidget->setText("i can change my custom widget...");

//BUT i get this messages:

//Application Output is:
//Starting C:\TEST\test-build-desktop\release\test.exe...
//C:\TEST\test-build-desktop\release\test.exe exited with code -1073741515

/*Build Issues is:

release/moc_QGLabel.cpp:47: warning: 'QGLabel::staticMetaObject' redeclared
without dllimport attribute after being referenced with dll linkage

release/moc_QGLabel.cpp:56: warning: 'virtual const QMetaObject* QGLabel::metaObject()
const' redeclared without dllimport attribute: previous dllimport ignored

release/moc_QGLabel.cpp:61: warning: 'virtual void* QGLabel::qt_metacast(const char*)'
redeclared without dllimport attribute: previous dllimport ignored

release/moc_QGLabel.cpp:69: warning: 'virtual int QGLabel::qt_metacall
(QMetaObject::Call, int, void**)' redeclared without dllimport attribute: previous dllimport ignored
*/



/*********************************************
i found in Qt Centre Forum FAQ
-1073741515 in dec is C0000135 in hex, which is a "dll file not found" error.
but i confused i added my dll, hmmm...!!!???
*/
//-------------------------------------------------------------------------


// so i dont know how i can do that, is other way, i dont know how i can use
// my plugin dll
// any suggestion? with a simple example!?!

//THANKs in Advance
//Regards Serjik

return app.exec();
}

//================================================== ==========

high_flyer
5th May 2011, 08:54
Please use code tags for code.

You have to decide what it is you want.
If you want to use a plugin, and load it dynamically, you don't want to link to it at build time.
The whole idea of a plugin is that your application is not dependent on it - especially not during build time.
So your original pro file was just fine, as you said you did manage to load the plugin and you could see your custom widgets in the GUI.

You didn't answer my last question.

serjik
5th May 2011, 09:46
Hello, i change my pro file
i have to extend ((# install)) part because my compiler was crashed,
//================================================== ==========
my test.pro file:


QT += core gui

CONFIG += uitools

#LIBS += c:/QGLabelPlugin_Release.dll

INCLUDEPATH += C:/ \
C:/TEST/test1

RESOURCES += test.qrc

SOURCES += main.cpp

#HEADERS += QGLabel.h


# install
target.path = C:/TEST/test1
sources.files = $$SOURCES $$HEADERS $$RESOURCES test.pro files
sources.path = C:/TEST/test1
INSTALLS += target sources

//================================================== ==========
main.cpp


#include <QApplication>
#include <QUiLoader>
#include <QWidget>
#include <QFile>
#include <QMainWindow>
#include <QtGui>
#include "QLabel.h"
#include "QGLabel.h"//???????????????????
//Qt 4.7.0
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(test);

QApplication app(argc, argv);

QUiLoader loader;
QFile uiFile(":/test.ui");
uiFile.open(QIODevice::ReadOnly);
QWidget *ui = loader.load(&uiFile);
uiFile.close();

qDebug() << loader.pluginPaths();
ui->show();
//after loading this form i need to access its child widgets

QList<QGLabel*> lstLabels = ui->findChildren<QGLabel*>();////////////////////////

return app.exec();
}


//================================================== ==========
ERROR::::::::::::::::::::::

g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads -Wl -Wl,-subsystem,windows -o release\test.exe release/main.o release/qrc_test.o -L"c:\Qt\2010.05\qt\lib" -lmingw32 -lqtmain -lQtUiTools -lQtXml4 -lQtGui4 -lQtCore4

release/main.o:main.cpp:(.text+0x304): undefined reference to `_imp___ZN7QGLabel16staticMetaObjectE'

collect2: ld returned 1 exit status

mingw32-make[1]: Leaving directory `C:/TEST01/test-build-desktop'

mingw32-make: Leaving directory `C:/TEST01/test-build-desktop'

mingw32-make[1]: *** [release\test.exe] Error 1

mingw32-make: *** [release] Error 2

The process "C:/Qt/2010.05/mingw/bin/mingw32-make.exe" exited with code %2.
Error while building project test (target: Desktop)
When executing build step 'Make'
//================================================== ==========
thank you.

high_flyer
5th May 2011, 10:02
do you read the responses you get here at all?

serjik
5th May 2011, 10:14
Yes i read, i cant understand what can i do?

high_flyer
5th May 2011, 10:23
What didn't you understand from what I wrote in my last 3 posts?

what can i do?
Ask for clarification, don't just ignore.

Do you understand what using code tags means?

SamFredericks
5th May 2011, 11:18
release/main.o:main.cpp:(.text+0x304): undefined reference to `_imp___ZN7QGLabel16staticMetaObjectE'


I think the compiler finds the declaration of QGLabel, but the linker can't find the sourcecode of QGLabel, because it does not exists in your prog. But it is logic...

First, you have to create your lib - for example "qglabel". Here you have to export (Q_DECL_EXPORT) your class QGLabel. Perhaps use the template fo QtCreator. This lib you have to use in your QGLabelPlugin.
Use in your *.pro-File of your QGLabelPlugin (I think because of mingw32 different notation in LIBS...):


# where your lib is stored
LIBS += -L"c:/TEST/bin" -lqglabel
# where the header is stored
INCLUDEPATH *= C:/TEST/src

This lib you have to use in your Main-Prog, too, beacuse you want to use the class QGLabel.
Use in your *.pro-File of your Main-Prog:


# where your lib is stored
LIBS += -L"c:/TEST/bin" -lqglabel
# where the header is stored
INCLUDEPATH *= C:/TEST/src


The QUiLoader needs the Plugins of the QtDesigner, too. Because of this, you have to say the QUiLoader where your Plugin is stored.
I hope I could help a little bit.

---------------------------------------------------------------------------------------------------------
EDIT

But the implementation is in the plugin, which is loaded.
That's right. @serjik: Sorry for confusing.

high_flyer
5th May 2011, 11:59
I think the compiler finds the declaration of QGLabel, but the linker can't find the sourcecode of QGLabel, because it does not exists in your prog.
But the implementation is in the plugin, which is loaded.
In such a case it should be enough if he has the header for the signatures, the address of the object is loaded via the plugin, if it was not, he could not have seen an instance of his custom widget in the GUI. (which is my understanding that he does)
The instance of his custom widget is in the gui, his problem is (if I understood correctly) is that he is unable to get the instance of it.
Even if he wouldn't be able to call functions on his custom widget pointer (which i think he should in this case) he should be able to receive valid address at least.

serjik
5th May 2011, 20:51
Hello guys,

high_flyer: What didn't you understand from what I wrote in my last 3 posts?
OK 1)QStringList strlPaths = loader.pluginPaths (); its shoes QUiLoader available plugins paths in a QStringList .
2)QList<QGLabel*> lstLabels = ui->findChildren<QGLabel*>();
generate a QList with QGLabel class type and fill lstLabels with ui's QGLabel type CHILDREN, this is i exactly need, i need to access my ui widgets(custom plugins)

---------------------------------------------------------------------------

SamFredericks thank you for reply, i try your idea....


---------------------------------------------------------------------------
I love you Qt BUT why you have not any sample for my problem ;()

high_flyer
6th May 2011, 08:44
generate a QList with QGLabel class type and fill lstLabels with ui's QGLabel type CHILDREN, this is i exactly need, i need to access my ui widgets(custom plugins)
Well, do you get an empty list or not?

serjik
14th May 2011, 06:09
Hello high_flyer, sorry for my late,

Well, do you get an empty list or not?
yes i get an empty list, any idea?

high_flyer
14th May 2011, 12:29
well, either what you are reporting is incorrect, or something else is wrong.
If the list you get is empty, it means there are no QGLabel objects in your ui - but you claim you see them.
So I don't know what to tell you.

serjik
14th May 2011, 14:27
Dear Sir, i design a ui file with QtDesigner and i use for example Qt's standard widget same as QLabel, after loading this ui file by UiLoader, i can make a QList and accsess all this widgets, but problem is in custom widgets , when i use them and after loading ui file by UiLoader, i can see loaded custom widgets but when i try to access them by using QList<QGLabel*> lstLabels = ui->findChildren<QGLabel*>(); the list is empty,
is it possible a LIB error? or can u show a sample? PLEASE...:confused:

high_flyer
14th May 2011, 16:14
As I said, I can't explain the behavior your are experiencing.
Maybe someone else can help you further.

Good luck!

high_flyer
16th May 2011, 15:18
Are your QGLabels children of the form widget, or are they children of another widget on the forum?
If the later, you will have first to extract the parent of your QGLabels, and call findChildren() on that widget.

serjik
23rd May 2011, 09:27
Thanks high_flyer,
I fix my problem by reading this link:
http://doc.qt.nokia.com/latest/designer-using-a-ui-file.html
But I didnt use UiLoader,Regards Lopez.

high_flyer
23rd May 2011, 10:08
Would be nice if you explain what the problem was - and how you solved it - for other users that might have a similar problem.

serjik
8th June 2011, 08:59
Hi, you can find a sample source code in this Thread: Ui file loaded by UiLoader , but NULL pointer to custom widgets" (http://www.qtcentre.org/threads/41648-Ui-file-loaded-by-UiLoader-but-NULL-pointer-to-custom-widgets?p=193403#post193403), Regards Serjik.