从现有的Qt类创建类

时间:2011-07-10 12:27:24

标签: qt class

我已经阅读了Qt 4.7 C ++教程,并且我已经启动了一个项目来扩展QTreeView的一些功能。

我正在尝试执行以下操作:

  1. 使用QTreeView
  2. 确保程序正常运行
  3. 根据.. \ src \ gui \ itemviews \ qtreeview.cpp,qtreeview.h和qtreeview_p.h
  4. 复制和粘贴新文件
  5. 在每个文件名和每个文件(包括.pro文件)中将“QTreeView”替换为“CustomTreeView”
  6. 我收到以下警告(使用MSVC,命令行):

    .\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
    
    '{ctor}'

    此尝试只出现一个错误,它与(动态编译的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
    

    不确定它是否告诉我与警告原因有关的任何内容。这是代码的嗤之以鼻:

    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)" (??1QAbstractItemViewPrivate@@UAE@XZ) referenced in function __unwindfunclet$??0SummaryDrillDownTreeView2Private@@QAE@XZ$0
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: __thiscall QAbstractItemViewPrivate::QAbstractItemViewPrivate(void)" (??0QAbstractItemViewPrivate@@QAE@XZ) referenced in function "public: __thiscall SummaryDrillDownTreeView2Private::SummaryDrillDownTreeView2Private(void)" (??0SummaryDrillDownTreeView2Private@@QAE@XZ)
    SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_rowsRemoved(class QModelIndex const &,int,int)" (?_q_rowsRemoved@QAbstractItemViewPrivate@@UAEXABVQModelIndex@@HH@Z)
    SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_columnsInserted(class QModelIndex const &,int,int)" (?_q_columnsInserted@QAbstractItemViewPrivate@@UAEXABVQModelIndex@@HH@Z)
    SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_layoutChanged(void)" (?_q_layoutChanged@QAbstractItemViewPrivate@@UAEXXZ)
    SummaryDrillDownTreeView2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::selectAll(class QFlags<enum QItemSelectionModel::SelectionFlag>)" (?selectAll@QAbstractItemViewPrivate@@UAEXV?$QFlags@W4SelectionFlag@QItemSelectionModel@@@@@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 " (?position@QAbstractItemViewPrivate@@UBE?AW4DropIndicatorPosition@QAbstractItemView@@ABVQPoint@@ABVQRect@@ABVQModelIndex@@@Z)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: void __thiscall QAbstractItemViewPrivate::doDelayedItemsLayout(int)" (?doDelayedItemsLayout@QAbstractItemViewPrivate@@QAEXH@Z) referenced in function "public: void __thiscall SummaryDrillDownTreeView2::setRowHidden(int,class QModelIndex const &,bool)" (?setRowHidden@SummaryDrillDownTreeView2@@QAEXHABVQModelIndex@@_N@Z)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: void __thiscall QAbstractItemViewPrivate::interruptDelayedItemsLayout(void)const " (?interruptDelayedItemsLayout@QAbstractItemViewPrivate@@QBEXXZ) referenced in function "public: void __thiscall SummaryDrillDownTreeView2::expandAll(void)" (?expandAll@SummaryDrillDownTreeView2@@QAEXXZ)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_modelDestroyed(void)" (?_q_modelDestroyed@QAbstractItemViewPrivate@@UAEXXZ) referenced in function "public: virtual void __thiscall SummaryDrillDownTreeView2Private::_q_modelDestroyed(void)" (?_q_modelDestroyed@SummaryDrillDownTreeView2Private@@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 " (?draggablePaintPairs@QAbstractItemViewPrivate@@UBE?AV?$QList@U?$QPair@VQRect@@VQModelIndex@@@@@@ABV?$QList@VQModelIndex@@@@PAVQRect@@@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 " (?draggablePaintPairs@SummaryDrillDownTreeView2Private@@UBE?AV?$QList@U?$QPair@VQRect@@VQModelIndex@@@@@@ABV?$QList@VQModelIndex@@@@PAVQRect@@@Z)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: class QStyleOptionViewItemV4 __thiscall QAbstractItemViewPrivate::viewOptionsV4(void)const " (?viewOptionsV4@QAbstractItemViewPrivate@@QBE?AVQStyleOptionViewItemV4@@XZ) referenced in function "protected: void __thiscall SummaryDrillDownTreeView2::drawTree(class QPainter *,class QRegion const &)const " (?drawTree@SummaryDrillDownTreeView2@@IBEXPAVQPainter@@ABVQRegion@@@Z)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: struct QEditorInfo __thiscall QAbstractItemViewPrivate::editorForIndex(class QModelIndex const &)const " (?editorForIndex@QAbstractItemViewPrivate@@QBE?AUQEditorInfo@@ABVQModelIndex@@@Z) referenced in function "protected: virtual void __thiscall SummaryDrillDownTreeView2::drawRow(class QPainter *,class QStyleOptionViewItem const &,class QModelIndex const &)const " (?drawRow@SummaryDrillDownTreeView2@@MBEXPAVQPainter@@ABVQStyleOptionViewItem@@ABVQModelIndex@@@Z)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: void __thiscall QFramePrivate::updateStyledFrameWidths(void)" (?updateStyledFrameWidths@QFramePrivate@@QAEXXZ) referenced in function "public: void __thiscall SummaryDrillDownTreeView2Private::initialize(void)" (?initialize@SummaryDrillDownTreeView2Private@@QAEXXZ)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(class QModelIndex const &,int,int)" (?_q_columnsAboutToBeRemoved@QAbstractItemViewPrivate@@UAEXABVQModelIndex@@HH@Z) referenced in function "public: virtual void __thiscall SummaryDrillDownTreeView2Private::_q_columnsAboutToBeRemoved(class QModelIndex const &,int,int)" (?_q_columnsAboutToBeRemoved@SummaryDrillDownTreeView2Private@@UAEXABVQModelIndex@@HH@Z)
    SummaryDrillDownTreeView2.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall QAbstractItemViewPrivate::_q_columnsRemoved(class QModelIndex const &,int,int)" (?_q_columnsRemoved@QAbstractItemViewPrivate@@UAEXABVQModelIndex@@HH@Z) referenced in function "public: virtual void __thiscall SummaryDrillDownTreeView2Private::_q_columnsRemoved(class QModelIndex const &,int,int)" (?_q_columnsRemoved@SummaryDrillDownTreeView2Private@@UAEXABVQModelIndex@@HH@Z)
    debug\cashflow.exe : fatal error LNK1120: 16 unresolved externals
    

2 个答案:

答案 0 :(得分:6)

您应该使用继承来创建新类,而不是复制和粘贴。保持这种方式的代码更少,并且即使是轻微的Qt升级也不太可能中断。

答案 1 :(得分:1)

我无法真正说出MSVC,但是这些成员被声明为QAbstractTreeView受保护,就像错误所说的那样。你没有粘贴与错误相关的源代码,但我猜你试图以某种方式使用那些不符合子类用法的受保护成员,可能是通过做一个实例并使用它?

编辑:

if ((state != QAbstractItemView::NoState

这是导致错误的实际行。在这里,您使用的是QAbstractView的受保护成员,这是不允许的,因为纯粹允许受保护的成员用于子类。

如果您的类继承了QAbstractView,您可以使用该成员。