2011-07-10 33 views
0

我已經通過了Qt 4.7 C++教程,並且我已經開始了一個項目來擴展QTreeView的某些功能。從現有的Qt類創建類

我試圖做到以下幾點:

  1. 確保程序運行正常使用QTreeView則
  2. 複製和粘貼新的文件基礎上.. \ SRC \ GUI \ itemviews \ qtreeview.cpp,QTreeView則.h和qtreeview_p.h
  3. 在每個文件名和每個文件中替換 「QTreeView則」 到 「CustomTreeView」(包括.pro文件)

我收到以下警告(使用MSVC,comman d線):

.\CustomTreeView.cpp(147) : warning C4273: 'CustomTreeView::CustomTreeView' : inconsistent dll linkage 
     c:\home\jetimms\code\projects\CustomTreeViewTest\CustomTreeView.hpp(31) : see previous definition of '{ctor}' 

還有很多這些警告,但它們看起來與上面相同。

另外,我有這些錯誤:

.\CustomTreeView.cpp(1216) : error C2248: 'NoState' : cannot access protected enumerator declared in class 'QAbstractItemView' 
    c:\qt\4.7.0\include\qtgui\../../src/gui/itemviews/qabstractitemview.h(304) : see declaration of 'NoState' 
    c:\qt\4.7.0\include\qtgui\../../src/gui/itemviews/qabstractitemview.h(63) : see declaration of 'QAbstractItemView' 
.\CustomTreeView.cpp(1216) : error C2248: 'EditingState' : cannot access protected enumerator declared in class 'QAbstractItemView' 
    c:\qt\4.7.0\include\qtgui\../../src/gui/itemviews/qabstractitemview.h(307) : see declaration of 'EditingState' 
    c:\qt\4.7.0\include\qtgui\../../src/gui/itemviews/qabstractitemview.h(63) : see declaration of 'QAbstractItemView' 

上面抱怨的下面(在qtreeview.h)與除與CustomTreeView替換QTreeView則沒有變化的等效:

bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) 
{ 
    Q_Q(QTreeView); 
    // we want to handle mousePress in EditingState (persistent editors) 
    if ((state != QAbstractItemView::NoState 
     && state != QAbstractItemView::EditingState) 
     || !viewport->rect().contains(pos)) 
     return true; 

    int i = itemDecorationAt(pos); 
    if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) { 
     if (viewItems.at(i).expanded) 
      collapse(i, true); 
     else 
      expand(i, true); 
     if (!isAnimating()) { 
      q->updateGeometries(); 
      viewport->update(); 
     } 
     return true; 
    } 
    return false; 
} 

我已經將這些新文件包含在SOURCES和HEADERS中的.pro文件中。上面的警告說我沒有包含構造函數的額外版本。

更新:20110710_0926

下面是導致錯誤的實際代碼:

bool CustomTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) { 
    Q_Q(CustomTreeView); 
    // we want to handle mousePress in EditingState (persistent editors) 
    if ((state != QAbstractItemView::NoState 
     && state != QAbstractItemView::EditingState) 
     || !viewport->rect().contains(pos)) 
    return true; 

    int i = itemDecorationAt(pos); 
    if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) { 
    if (viewItems.at(i).expanded) 
     collapse(i, true); 
    else 
     expand(i, true); 
    if (!isAnimating()) { 
     q->updateGeometries(); 
     viewport->update(); 
    } 
    return true; 
    } 
    return false; 
} 

更新20110710_1339:

當我試圖編譯(使用qmake的,如前)用.. \ src \ gui \ itemviews \中的qtreeview文件替換我的自定義類,我收到了非常類似的警告。

c:\Qt\4.7.0\src\gui\itemviews\qtreeview.cpp(187) : warning C4273: 'QTreeView::QTreeView' : inconsistent dll linkage 
    c:\qt\4.7.0\src\gui\itemviews\qtreeview.h(74) : see previous definition 
的「{}構造函數」

只有一個與此嘗試會出現錯誤,它與做(moc_qtreeview.cpp這是對飛編譯):

C:\home\jetimms\code\projects\cashflow\debug\moc_qtreeview.cpp(95) : error C2491: 'QTreeView::staticMetaObject' : definition of dllimport static data member not allowed 

不確定它是否告訴我有關警告原因的任何事情。下面是代碼SNIPPIT:

const QMetaObject QTreeView::staticMetaObject = { 
    { &QAbstractItemView::staticMetaObject, qt_meta_stringdata_QTreeView, 
     qt_meta_data_QTreeView, 0 } 
}; 

我只是覺得很奇怪,QTreeView則文件本身錯誤,當我試圖與他們建立。

無論如何,警告告訴我,QTreeView的構造函數已經被定義。我對所有的頭文件都有保護,所以我無法想象它會認爲QTreeView被定義了兩次。

更新:20110710_1612

這裏是QTreeView.h與QTreeView則定義開始。請注意,它包含QAbstractItemView.h並從中繼承。

#include <QtGui/qabstractitemview.h> 
QT_BEGIN_HEADER 
QT_BEGIN_NAMESPACE 
QT_MODULE(Gui) 
#ifndef QT_NO_TREEVIEW 
class QTreeViewPrivate; 
class QHeaderView; 
class Q_GUI_EXPORT QTreeView : public QAbstractItemView 
{ 
    ... 

以完全相同的方式,我的自定義類繼承自它。

#include <QtGui/qabstractitemview.h> 
QT_BEGIN_HEADER 
QT_BEGIN_NAMESPACE 
QT_MODULE(Gui) 
#ifndef QT_NO_TREEVIEW 
class CustomTreeViewPrivate; 
class QHeaderView; 
class Q_GUI_EXPORT CustomTreeView : public QAbstractItemView 
{ 

更新:20110710_1757

我漸漸明白,我是從QTreeView則複製代碼是一個圖書館,我不建庫,只需將.exe我的應用程序。我從構造函數中刪除了Q_GUI_EXPORT(剛剛在上面),並且我遇到的警告消失了。

現在我正在處理的moc_CustomTreeView.cpp文件中的錯誤(有3個錯誤的一切,都像這樣):

debug\moc_CustomTreeView.cpp(140) : error C2027: use of undefined type 'CustomTreeViewPrivate' 
     c:\home\jetimms\code\projects\cashflow\debug\../CustomTreeView.hpp(12) : see declaration of 'CustomTreeViewPrivate' 
debug\moc_CustomTreeView.cpp(140) : error C2227: left of '->_q_endAnimatedOperation' must point to class/struct/union/generic type 

這裏是有問題的代碼:

case 16: d_func()->_q_endAnimatedOperation(); break; 

不知道該怎麼做moc_文件錯誤。 d_func()獲取CustomTreeViewPrivate實例,但moc_文件作用域無法看到它。

更新:20110710_1757

我環顧四周,瞭解moc_文件和開發的Qt的方式,發現這兩個。 KDE Techbase Policies/Library Code Policy這個解釋了爲什麼使用私有類等寫入Qt代碼的原因。

我還發現了下面這個頁面,它解釋了當你的moc_代碼給你錯誤時,如上面的錯誤(重新運行qmake),Using the Meta-Object Compiler (moc)。我試過這個,上面的moc_錯誤消失了,現在我得到了這些。

再次,我將CustomTreeView名稱更改爲SummaryDrillDownTreeView2。

SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall QAbstractItemViewPrivate::~QAbstractItemViewPrivate(void)" ([email protected]@[email protected]) referenced in function [email protected]@[email protected]$0 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: __thiscall QAbstractItemViewPrivate::QAbstractItemViewPrivate(void)" ([email protected]@[email protected]) referenced in function "public: __thiscall SummaryDrillDownTreeView2Private::SummaryDrillDownTreeView2Private(void)" ([email protected]@[email protected]) 
SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_rowsRemoved(class QModelIndex const &,int,int)" ([email protected]@@[email protected]@[email protected]) 
SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_columnsInserted(class QModelIndex const &,int,int)" ([email protected]@@[email protected]@[email protected]) 
SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_layoutChanged(void)" ([email protected]@@UAEXXZ) 
SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::selectAll(class QFlags<enum QItemSelectionModel::SelectionFlag>)" ([email protected]@@[email protected]@[email protected]@@@@Z) 
SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual enum QAbstractItemView::DropIndicatorPosition __thiscall QAbstractItemViewPrivate::position(class QPoint const &,class QRect const &,class QModelIndex const &)const " ([email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@@Z) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: void __thiscall QAbstractItemViewPrivate::doDelayedItemsLayout(int)" ([email protected]@@[email protected]) referenced in function "public: void __thiscall SummaryDrillDownTreeView2::setRowHidden(int,class QModelIndex const &,bool)" ([email protected]@@[email protected]@[email protected]) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: void __thiscall QAbstractItemViewPrivate::interruptDelayedItemsLayout(void)const " ([email protected]@@QBEXXZ) referenced in function "public: void __thiscall SummaryDrillDownTreeView2::expandAll(void)" ([email protected]@@QAEXXZ) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_modelDestroyed(void)" ([email protected]@@UAEXXZ) referenced in function "public: virtual void __thiscall SummaryDrillDownTreeView2Private::_q_modelDestroyed(void)" ([email protected]@@UAEXXZ) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual class QList<struct QPair<class QRect,class QModelIndex> > __thiscall QAbstractItemViewPrivate::draggablePaintPairs(class QList<class QModelIndex> const &,class QRect *)const " ([email protected]@@[email protected][email protected]@@[email protected]@@@@@[email protected]@@@@[email protected]@@Z) referenced in function "public: virtual class QList<struct QPair<class QRect,class QModelIndex> > __thiscall SummaryDrillDownTreeView2Private::draggablePaintPairs(class QList<class QModelIndex> const &,class QRect *)const " ([email protected]@@[email protected][email protected]@@[email protected]@@@@@[email protected]@@@@[email protected]@@Z) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: class QStyleOptionViewItemV4 __thiscall QAbstractItemViewPrivate::viewOptionsV4(void)const " ([email protected]@@[email protected]@XZ) referenced in function "protected: void __thiscall SummaryDrillDownTreeView2::drawTree(class QPainter *,class QRegion const &)const " ([email protected]@@[email protected]@[email protected]@@Z) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: struct QEditorInfo __thiscall QAbstractItemViewPrivate::editorForIndex(class QModelIndex const &)const " ([email protected]@@[email protected]@[email protected]@@Z) referenced in function "protected: virtual void __thiscall SummaryDrillDownTreeView2::drawRow(class QPainter *,class QStyleOptionViewItem const &,class QModelIndex const &)const " ([email protected]@@[email protected]@[email protected]@[email protected]@@Z) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: void __thiscall QFramePrivate::updateStyledFrameWidths(void)" ([email protected]@@QAEXXZ) referenced in function "public: void __thiscall SummaryDrillDownTreeView2Private::initialize(void)" ([email protected]@@QAEXXZ) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(class QModelIndex const &,int,int)" ([email protected]@@[email protected]@[email protected]) referenced in function "public: virtual void __thiscall SummaryDrillDownTreeView2Private::_q_columnsAboutToBeRemoved(class QModelIndex const &,int,int)" ([email protected]@@[email protected]@[email protected]) 
SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_columnsRemoved(class QModelIndex const &,int,int)" ([email protected]@@[email protected]@[email protected]) referenced in function "public: virtual void __thiscall SummaryDrillDownTreeView2Private::_q_columnsRemoved(class QModelIndex const &,int,int)" ([email protected]@@[email protected]@[email protected]Z) 
debug\cashflow.exe : fatal error LNK1120: 16 unresolved externals 
+0

這個問題變得混亂(這是我的錯,因爲我現在正在嘗試兩種方法)。我將把涉及從QTreeView繼承的第二種方法移到另一個問題。 – jetimms

回答

1

我真的不能說的MSVC,但這些成員被聲明爲受保護的QAbstractTreeView,像錯誤說。你沒有粘貼與錯誤相關的源代碼,但我想你正試圖使用​​那些受保護的成員以某種方式沒有資格作爲子類的用法,也許通過做一個實例並使用它?

編輯:

if ((state != QAbstractItemView::NoState 

這是導致錯誤的實際行。這裏您使用的是QAbstractView的受保護成員,因爲受保護的成員純粹被允許用於子類。

如果你的類繼承了QAbstractView,你可以使用該成員。

+0

我會編輯和添加代碼,但它幾乎是逐字的,包含在QTreeView頭文件中(如上所示),即沒有顯着差異,我可以說。 – jetimms

+0

你是對的。我確實找到了一個叫做State的受保護的枚舉,它在QAbstractItemView.h中設置了'NoState'類型。但是,QTreeView和我的自定義類都從QAbstractItemView繼承,所以我認爲他們都可以使用這個枚舉,而不僅僅是QTreeView,因爲它似乎是從我的第二次嘗試中發生的。我將把QTreeView.h文件中的類聲明和少量正在進行的宏添加到上面的問題中。 – jetimms

+1

您需要像CustomTreeView :: NoState一樣使用它,而不是QAbstr ... :: NoState,後者以公開的方式使用它,因爲您不屬於該類。 – Smar

6

您應該使用繼承來創建新類,而不是複製和粘貼。維護這種方式的代碼較少,即使是較小的Qt升級也不太可能。

+0

這是我第一次嘗試的,然而,我想改變的QTreeView的方法不是虛擬的。我認爲它違背慣例重新定義了一個繼承的非虛擬方法。 – jetimms

+1

不知道你在做什麼,不可能說。你確定你想要一個樹形視圖嗎? – Bill99

+0

我會在上面解釋。 – jetimms