Qt Designer undefined symbol with Custom Widget plugin - c++

I am using Qt 4.7.2 under Fedora 14.
I have a working library of custom widgets which I am trying to integrate into Qt Designer.
There is a simple widget base class, then some more complex widgets inheriting from it.
The simple widget integrates fine, but I have a problem with the more complex ones.
The problem comes from the fact that that the more complex ones require a special structure to be passed to them on creation. So my code for creating a complex widget in the plugin is:
QWidget *myPlugin::createWidget(QWidget *parent)
{
my_struct *xyz = new my_struct;
return new myWidget("MyWidget",xyz, parent);
}
my_struct is just a simple C style struct with ints, doubles and arrays.
Then when I start Qt Designer with this plugin I get:
/usr/lib64/qt4/bin/designer: symbol lookup error: /usr/lib64/qt4/plugins/designer/libMyPlugin.so: undefined symbol: _ZN8MyWidgetC1E7QStringP17my_structP7QWidget
I am building a release version of the plugin, not a debug version.
I also tried defining xyz as a static class variable in the plugin and just passing its address to the constructor, but I still get the same error.
I also tried adding xyx as an unused static class variable to my simple widget and that does not give the error, so the error seems to be coming from the call to the myWidget constuctor.
Can anyone help me resolve this?
Thanks Arne,
You were right.
I added my library explicitly to the plugin's .pro file and then it worked.
What puzzles me is how could I build the plugin with no errors without the library?
And why did my simple widget work without the library?

The error message looks as if the linker did not find a definition for the constructor myWidget(QString, my_struct*, QWidget*). Have you added the relevant source file to your release build? Do you actually have a definition for this constructor? It is also possible that you have to exchange the object file linking order. I have seen this with larger projects in the past, so I wouldn't be too surprised. The object file containing the definition needs to be stated before the one using the definition.

Related

wxWidgets - Splitting project into multiple files

I am very new to C++, I'm making this music application using wxWidgets, this is my first project in C++. As of now, I have 4 files, app.hpp and app.cpp which has a class that inherits from wxApp that launches the application, and frame.hpp and frame.cpp which holds the base frame and panel, and all the widgets, and their appropriate functions. I want to move all the functions to a separate file, but I get some errors like there is this function in frame.cpp
void Frame::ClearPlaylist(wxCommandEvent& event)
{
mediaCtrl->Stop();
playlistBox->Clear();
}
I tried moving it in another file called command.cpp and created a new class called command and prefixed all functions to Command:: .... and somethings like the playlistBox here, is a widget which I want in frame.cpp only, as it is a widget, so I did #include frame.hpp and prefixed it with Frame::playlistBox, but that gave a error saying invalid use of non static data member. So do I have to make everything in frame.hpp a static object? Or if anyone has a better solution for organizing a project like this please do share.

Qt two QList member variables causes crash

so I'm not sure if this is a bug in Qt or if I just don't understand something, but i have this class:
class myClass : public QDialog, private Ui::myClass
{
Q_OBJECT
public:
explicit myClass(QWidget *parent = 0);
private:
QList<ushort> list1;
QList<ushort> list2;
}
I create this window by clicking on an action in another window:
void mainWindow::on_myClassAction_triggered()
{
myClass *mc = new mc(NULL);
mc->show();
}
So now things get weird. Even if i don't use list1 and list2 anywhere in myClass, the program will crash when i close or sometimes open myClass. If i comment out one, or both of them, it works. What is going on here??
I'm using Qt Creator. I just re-ran QMake and now it works. Definitely was some sort of bug within Qt/Qt Creator.
This is not a bug of any sort. It's a classic binary incompatibility problem: you've had some code that depended on the layout of some of your classes, but the outdated Makefiles did not capture that dependency. Thus when you changed the layout of the class, the dependent code didn't get recompiled. It would be way too expensive for qmake to rescan the entire project looking for such dependencies every time you build it. It's on you to re-run qmake when you change the code to introduce such binary incompatibilities.
For small projects, you may simply wish to always rebuild the code, forcing a qmake re-run.

Qt: Generate ui_ classes using uic, load dynamically by class name

Is it possible to load an .ui class generated by uic, dynamically by class name? I need to decide which UI class to load dynamically. I do not have that information at compile time. I do not want to use QUiLoader. Instead, I want to combine the direct approach here with QMetaType object instantiation by string.
I.e.
add the UI file to FORMS in project file,
declare the UI classes for QMetaType usage Q_DECLARE_METATYPE(Ui::planar_break) or Q_DECLARE_METATYPE(Ui_planar_break)
then form a string class name dynamically depending on user action: "Ui::planar_break" or "Ui_planar_break"
and invoke the below function to get the UI widget pointer for usage?
QWidget* initiateClassByName(QString name){
int id = QMetaType::type(name.toLatin1());
QWidget* widget=nullptr;
if (id != QMetaType::UnknownType) {
widget=static_cast< QWidget* > (QMetaType::create(id));
//QMetaType::destroy(id, myClassPtr);
//myClassPtr = 0;
}
return widget;
}
I am trying to increase the performance, compared to loading a dozen or so UI files (stored in Qt resource files) dynamically every time a specific dialog is instantiated. When I do this I seem to get a QMetaType::UnknownType every time. Ideas? Thanks.
(Hm, not sure why my function wasn't showing as code block here, until I made it a quotation.)
uic creates C++ code. If you really want to dynamically create a widget/dialog out of an xml file at runtime, you need to use the Qt Ui Tools. The class QUiLoader might be what you are looking for. If you do this, you can query the created QWidget through QWidget::findChild You can interact with the UI items through QObject::findChild(), provided you give your widgets distinct and meaningful object names.
Essentially, based on discussion had in #qt irc channel on Freenode I think what I am asking is actually not feasible.
My understanding is that even if I could get the C++ headers compiled and the classes registered using perhaps also qRegisterMetaType(), and perhaps even get them instantiated using QMetaType, to actually get the UI built I would have to call setupUi() on the instance.
Since UI files do not implement a common interface that includes setupUi, and I don't know compile-time which class I am instantiating, calling setupUi becomes impossible.

Standard and "exotic" icons

I'm trying to use the standard icons in Qt for a QToolButton but I have a problem. My code is:
m_buttonZoomPlus->setIcon(QStyle::standardIcon(QStyle::SP_DesktopIcon));
I get the error message :
cannot call member function 'QIcon QStyle::standardIcon(QStyle::StandardPixmap, const QStyleOption*, const QWidget*) const' without object
What does it mean? Do I Have to create an empty QStyle object and call the standardIcon function on it?
Besides, I found a list of standard icons here: http://doc.trolltech.com/main-snapshot/qstyle.html#StandardPixmap-enum
Is this list exhaustive or are there other standard icons? I'm looking for instance for a zoom-in/out icon and I've not yet been able to find it.
Thank you very much for you help.
It means standardIcon is not a static method so you can't call it that way. You need to construct a QStyle and initialize it appropriately then you can use that method to get a specific icon.
Edit: Jeremy is right. If you aren't changing the style or defining your own style you can simply use the following:
QApplication::style()->standardIcon(QStyle::SP_DesktopIcon);
Reference: http://doc.qt.io/qt-5/qstyle.html#standardIcon

Eclipse CDT "New Class" Template

I have been using Eclipse CDT for some time now, and I love it, but there are a few tedious things that I would like to fix up about it.
When you create a new file, one of the options is "New"->"Class". I was wondering if anyone knows of a way to edit the "${declarations}" section of this "Class" template.
To be more specific, I have looked through the "Window"->"Preferences" menu and been unable to find anything. I have changed both "C/C++"->"Code Style"->"Code Templates" and "C/C++"->"Editor"->"Templates". Only the first of the two actually seems to change what appears upon class creation, and it doesn't let me change what is in the "${declarations}" section. Does anyone know how to change this?
Thanks,
Chris
The preference C/C++ -> Editor -> Templates is used by the templates which are inserted manually via Context Assist. Try create a new file, type clas and press ctrl+space for context assist. You should get two assist proposals: a keyword proposal and a template proposal (the latter will also be triggered automatically as default if you type class and press ctrl+space).
Upon selection of the template proposal, a class body will be generated according to the template which you can define in this preference.
As for C/C++ -> Code Style -> Code Templates, this is used in automatic generation. When you use the New Class wizard, the Default C++ Source template and Default C++ Header template are used and the $(declarations) variable is replaced by whatever code is generated by the New Class wizard.
This would mean that you can use a custom template by triggering one of the Editor templates manually, possibly via creating a named class with New Class wizard and then replacing the default class body in header by your custom template.
Or do you suggest that the New Class wizard lacks any important fields and should be extended?
Or do you suggest that the New Class wizard lacks any important fields and should be extended?
Yes private copy and assign operator.
Oooh! Finally found an answer.
In Eclipse CDT (Juno), go to File -> Preferences.
Navigate to the following pane on the left panel of the Preferences window: C/C++ -> Code Style -> Code Templates.
In the Code Templates window, navigate to Files -> C++ Header File.
Edit the header file:
Remove the ${declarations} line, and insert your own stuff.
This has the somewhat unfortunate disadvantage of losing everything that the New Class Wizard would produce. This might invalidate any inherited classes or other things you might select from the New Class Wizard, but I haven't checked.
Here's my C++ Header File Template:
${filecomment}
#ifndef ${include_guard_symbol}
#define ${include_guard_symbol}
${includes}
${namespace_begin}
class ${type_name}
{
public:
/* Default Constructor */
${type_name}();
/* Deconstructor */
virtual ~${type_name}();
private:
/* Disable the following by default */
${type_name}(const ${type_name}& other);
${type_name}& operator=(const ${type_name}&);
};
${namespace_end}
#endif /* ifndef ${include_guard_symbol} */
Hope this helps!