undefined reference to `QAbstractItemViewPrivate::...
-
I am trying to do a new QAbstractItemView derived View/Widget with private data.
Everything compiles but do not link... with the following errors:
debug/QBinaryTreeView_p.o: In function
ZN22QBinaryTreeViewPrivateC2Ev': F:\_svn\Qt\Programs\build-QBinaryTreeTest-Desktop_Qt_5_4_1_MinGW_32bit-Debug/../QBinaryTreeTest/QBinaryTreeView_p.cpp:10: undefined reference to
QAbstractItemViewPrivate::QAbstractItemViewPrivate()'
debug/QBinaryTreeView_p.o: In functionZN22QBinaryTreeViewPrivateD2Ev': F:\_svn\Qt\Programs\build-QBinaryTreeTest-Desktop_Qt_5_4_1_MinGW_32bit-Debug/../QBinaryTreeTest/QBinaryTreeView_p.cpp:15: undefined reference to
QAbstractItemViewPrivate::~QAbstractItemViewPrivate()'
debug/QBinaryTreeView_p.o:QBinaryTreeView_p.cpp:(.rdata$_ZTV22QBinaryTreeViewPrivate[__ZTV22QBinaryTreeViewPrivate]+0x48): undefined reference toQAbstractItemViewPrivate::_q_rowsRemoved(QModelIndex const&, int, int)' debug/QBinaryTreeView_p.o:QBinaryTreeView_p.cpp:(.rdata$_ZTV22QBinaryTreeViewPrivate[__ZTV22QBinaryTreeViewPrivate]+0x4c): undefined reference to
QAbstractItemViewPrivate::_q_rowsInserted(QModelIndex const&, int, int)'
debug/QBinaryTreeView_p.o:QBinaryTreeView_p.cpp:(.rdata$_ZTV22QBinaryTreeViewPrivate[__ZTV22QBinaryTreeViewPrivate]+0x50): undefined reference toQAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(QModelIndex const&, int, int)' debug/QBinaryTreeView_p.o:QBinaryTreeView_p.cpp:(.rdata$_ZTV22QBinaryTreeViewPrivate[__ZTV22QBinaryTreeViewPrivate]+0x54): undefined reference to
QAbstractItemViewPrivate::_q_columnsRemoved(QModelIndex const&, int, int)'
debug/QBinaryTreeView_p.o:QBinaryTreeView_p.cpp:(.rdata$_ZTV22QBinaryTreeViewPrivate[__ZTV22QBinaryTreeViewPrivate]+0x58): undefined reference to `QAbstractItemViewPrivate::_q_columnsInserted(QModelIndex const&, int, int)'It is either that there is a missing library in my project or my XXXPrivate class is not within the same namespace...
My project is like this:
#------------------------------------------------- # # Project created by QtCreator 2015-03-20T08:30:47 # #------------------------------------------------- QT += gui widgets core widgets-private gui-private core-private greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = QBinaryTreeTest TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ QBinaryTreeView.cpp \ QBinaryTreeView_p.cpp HEADERS += mainwindow.h \ QBinaryTreeView.h \ QBinaryTreeView_p.h ------------------------------------------ QBinaryTreeView.h: #ifndef QBINARYTREEVIEW_H #define QBINARYTREEVIEW_H #include <QAbstractItemView> QT_BEGIN_HEADER QT_BEGIN_NAMESPACE QT_MODULE(Gui) #ifndef QT_NO_BINARYTREEVIEW class QBinaryTreeViewPrivate; class QBinaryTreeView : public QAbstractItemView { Q_OBJECT Q_ENUMS(QBVFlow) Q_PROPERTY(int depth READ depth WRITE setDepth) Q_PROPERTY(QSize minimalItemSize READ minimalItemSize WRITE setMinimalItemSize) Q_PROPERTY(QBVFlow flow READ flow WRITE setFlow) public: QBinaryTreeView(); ~QBinaryTreeView(); ... private: Q_DECLARE_PRIVATE(QBinaryTreeView) Q_DISABLE_COPY(QBinaryTreeView) }; #endif // QT_NO_BINARYTREEVIEW QT_END_NAMESPACE QT_END_HEADER #endif // QBINARYTREEVIEW_H ------------------------------------------------------------- QBinaryTreeView_p.h: #ifndef QBINARYTREEVIEWPRIVATE_H #define QBINARYTREEVIEWPRIVATE_H #include <private/qabstractitemview_p.h> #ifndef QT_NO_BINARYTREEVIEW QT_BEGIN_NAMESPACE class QBinaryTreeViewPrivate : public QAbstractItemViewPrivate { public: QBinaryTreeViewPrivate(); ~QBinaryTreeViewPrivate(); }; QT_END_NAMESPACE #endif // QT_NO_BINARYTREEVIEW #endif // QBINARYTREEVIEWPRIVATE_H
Can anybody point me in the right direction please
Thanks
Edited - Put code after 3 backticks(```) and end with the same - p3c0
-
Hi and welcome to devnet
It looks like you do not include one of your own classes in the .pro file.
Most likely you have to add
SOURCES += main.cpp\ mainwindow.cpp \ QBinaryTreeView.cpp \ QBinaryTreeView_p.cpp \ qabstractitemview_p.cpp HEADERS += mainwindow.h \ QBinaryTreeView.h \ QBinaryTreeView_p.h \ qabstractitemview_p.h
Note: I might be confused with the naming of your classes. Most people avoid starting their own implementations with Q, but I assume that those implementation are your won code.
-
Thanks koahnig for the reply
Unfortunatly QAbstractItemViewPrivate is part of Qt's libarries...
QListWidget derives from QListView which derives from QAbstractItemView. QAbtractItemView uses as private data QAbtractItemViewPrivate. QLisWigdet's private data also derives from QAbtractItemViewPrivate.
So any application that uses QListWidget uses QAbtractItemViewPrivate.
No, I honestly feel that my declaration if faulty either because i am not in the same namespace or some library is missing from my project... Or the declaration order of my libraries is faulty.
qabstractitemview_p.h is available with the standard installation of Qt because it defines the content of an item in their libraries. qabstractitemview_p.cpp is not. The other option is to get the source and try to figure out the namespace used if any.
As for your note... Yes this is my own code. I intend to contribute by sending it, if they would accept it. This is why I want to do it right from the start.
-
Hi and welcome to devnet,
If you would like to contribute a new class to Qt, then you should rather put it directly in Qt's sources and build everything. That way you ensure that you have everything in place properly.
On a side note, why are you trying to build Qt's private classes in your application ? That will result in symbol duplication.
-
I want to derive from QAbstractItemViewPrivate to add properties I need for this new View. If I understood right, Views and Widgets as many other Qt classes, do not hold the data by itself, but rely on a private member variable to hold them, as long as some common functionalities.
As for symbol duplication, if I understood you right, the Private class that gives me trouble is intended only at this new View, not at my application. The Private Class is in the project file for my test application, because I found this convenient for the implementation of the view code (one project opened).
But I think you are right. The best way is to integrate my view and it's private class into the QtWidget library and use is.
Thanks
-
The classes rely on the private implementation (PIMPL idiom) to ensure the promised ABI compatibility between Qt major versions. Doing so allows to completely rewrite the internals of a class without requiring the user to rebuild their applications.
About the symbol duplication, I've mixed your code with the example from @koahnig, sorry. Your project on that side looks good.
On a side note, you should take a look for Qt's coding guide lines also for file naming.
-
Do you have a link were I can find this document. I will try to comply, but first I want to get this view working.
Thanks
-
-
Fixed...
I have incorporated my View to Qt's widget library and all works fine.
It is a bit long to compile on a cleaned package, but it works.
Thanks all for your help.
-
I currently have the same problem in Qt 5.6.2, I can not develop my own spinbox using QAbstractSpinBoxPrivate with the same error with undefined references to the QAbstractSpinBoxPrivate functions. With a few tests, I experienced the same for QAbstractButtonPrivate etc...
However, the test for QWidgetPrivate works. If you compare the declarations in the header files, you see that QWidgetPrivate is declared as "Q_WIDGETS_EXPORT" whereas QAbstractSpinBoxPrivate and QAbstractButtonPrivate are not (as is QAbstractItemViewPrivate). This is why it is not possible to derive those private classes when your code is not part of qt(widgets) itself.
I don't know if this behavior is intended. There are other private classes declared as "Q_WIDGETS_EXPORT" ( QAbstractItemViewPrivate is derived from QAbstractScrollAreaPrivate which is exported ), but i think that at least the "Abstract" private classes should be accessible as these widgets are designed to be customized.
I filed a suggestion as https://bugreports.qt.io/browse/QTBUG-57036