Qt错误:无效使用不完整类型'class QLabel'

时间:2014-02-14 15:22:36

标签: c++ qt

我正在尝试使用QtCreater编译以下程序,但是我在这个程序中遇到了很多错误。我从一本书中得到了这个程序,我无法弄清楚错误的位置。有人可以帮助调试这个程序。

这是FindDialog.h

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>

class QCheckbox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
    Q_OBJECT

public:
    FindDialog(QWidget *parent = 0);

signals:
    void findNext(const QString &str, Qt::CaseSensitivity cs);
    void findPrevious(const QString &str, Qt::CaseSensitivity cs);

private slots:
    void findClicked();
    void enableFindButton(const QString &text);

private:
    QLabel *label;
    QLineEdit *lineEdit;
    QCheckbox *caseCheckBox;
    QCheckbox *backwardCheckBox;
    QPushButton *findButton;
    QPushButton *closeButton;
};

#endif

FindDialog.cpp

#include <QtGui>

#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent) : QDialog(parent)
{
    label = new QLabel(tr("Find &what"));
    lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);
    caseCheckBox = new QCheckbox(tr("Match &case"));
    backwardCheckBox = new QCheckbox(tr("Search &backward"));
    findButton = new QPushButton(tr("&Find"));
    findButton->setDefault(true);
    findButton->setEnabled(false);
    closeButton = new QPushButton(tr("Close"));

    connect(lineEdit, SIGNAL(textChanged(const QString &)), 
            this, SLOT(enableFindButton(const QString &)));

    connect(findButton, SIGNAL(clicked()),
            this, SLOT(findClicked()));

    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));

    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    QVBoxLayout *leftLayout = new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Find"));
    setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
    QString text = lineEdit->text();
    Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseSensitivity
                                                       : Qt::CaseInsensitive;
    if(backwardCheckBox->isChecked()) {
        emit findPrevious(text, cs);
    } else {
        emit findNext(text, cs);
    }
}

void FindDialog::enableFindButton(const QString &text)
{
    findButton->setEnabled(!text.isEmpty());
}

的main.cpp

#include <QApplication>

#include "findDialog.h"

int main (int argc, char *argv[])
{
    QApplication app(argc, argv);
    FindDialog *dialog = new FindDialog;
    dialog->show();
    return app.exec();
}

我得到的错误如下:

finddialog.cpp:21:32: note: candidates are:
In file included from /usr/include/qt5/QtCore/qabstractanimation.h:45:0,
                 from /usr/include/qt5/QtCore/QtCore:4,
                 from /usr/include/qt5/QtGui/QtGui:4,
                 from finddialog.cpp:1:
/usr/include/qt5/QtCore/qobject.h:199:36: note: static QMetaObject::Connection QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
     static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                                    ^
/usr/include/qt5/QtCore/qobject.h:199:36: note:   no known conversion for argument 1 from ‘QPushButton*’ to ‘const QObject*’
/usr/include/qt5/QtCore/qobject.h:202:36: note: static QMetaObject::Connection QObject::connect(const QObject*, const QMetaMethod&, const QObject*, const QMetaMethod&, Qt::ConnectionType)
     static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
                                    ^
/usr/include/qt5/QtCore/qobject.h:202:36: note:   no known conversion for argument 1 from ‘QPushButton*’ to ‘const QObject*’
/usr/include/qt5/QtCore/qobject.h:418:32: note: QMetaObject::Connection QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
 inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,
                                ^
/usr/include/qt5/QtCore/qobject.h:418:32: note:   no known conversion for argument 1 from ‘QPushButton*’ to ‘const QObject*’
/usr/include/qt5/QtCore/qobject.h:215:43: note: template<class Func1, class Func2> static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType)
     static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                                           ^
/usr/include/qt5/QtCore/qobject.h:215:43: note:   template argument deduction/substitution failed:
/usr/include/qt5/QtCore/qobject.h: In substitution of ‘template<class Func1, class Func2> static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = const char*; Func2 = const char*]’:
finddialog.cpp:21:32:   required from here
/usr/include/qt5/QtCore/qobject.h:215:43: error: no type named ‘Object’ in ‘struct QtPrivate::FunctionPointer<const char*>’
/usr/include/qt5/QtCore/qobject.h:245:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<((int)(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2)
             connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
             ^
/usr/include/qt5/QtCore/qobject.h:245:13: note:   template argument deduction/substitution failed:
finddialog.cpp:21:32: note:   candidate expects 3 arguments, 4 provided
       this, SLOT(findClicked()));
                                ^
In file included from /usr/include/qt5/QtCore/qabstractanimation.h:45:0,
                 from /usr/include/qt5/QtCore/QtCore:4,
                 from /usr/include/qt5/QtGui/QtGui:4,
                 from finddialog.cpp:1:
/usr/include/qt5/QtCore/qobject.h:268:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2)
             connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
             ^
/usr/include/qt5/QtCore/qobject.h:268:13: note:   template argument deduction/substitution failed:
finddialog.cpp:21:32: note:   candidate expects 3 arguments, 4 provided
       this, SLOT(findClicked()));
                                ^
finddialog.cpp:23:61: error: no matching function for call to ‘FindDialog::connect(QPushButton*&, const char [11], FindDialog* const, const char [9])’
  connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
                                                             ^
finddialog.cpp:23:61: note: candidates are:
In file included from /usr/include/qt5/QtCore/qabstractanimation.h:45:0,
                 from /usr/include/qt5/QtCore/QtCore:4,
                 from /usr/include/qt5/QtGui/QtGui:4,
                 from finddialog.cpp:1:
/usr/include/qt5/QtCore/qobject.h:199:36: note: static QMetaObject::Connection QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
     static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                                    ^
/usr/include/qt5/QtCore/qobject.h:199:36: note:   no known conversion for argument 1 from ‘QPushButton*’ to ‘const QObject*’
/usr/include/qt5/QtCore/qobject.h:202:36: note: static QMetaObject::Connection QObject::connect(const QObject*, const QMetaMethod&, const QObject*, const QMetaMethod&, Qt::ConnectionType)
     static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
                                    ^
/usr/include/qt5/QtCore/qobject.h:202:36: note:   no known conversion for argument 1 from ‘QPushButton*’ to ‘const QObject*’
/usr/include/qt5/QtCore/qobject.h:418:32: note: QMetaObject::Connection QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
 inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,
                                ^
/usr/include/qt5/QtCore/qobject.h:418:32: note:   no known conversion for argument 1 from ‘QPushButton*’ to ‘const QObject*’
/usr/include/qt5/QtCore/qobject.h:215:43: note: template<class Func1, class Func2> static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType)
     static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                                           ^
/usr/include/qt5/QtCore/qobject.h:215:43: note:   template argument deduction/substitution failed:
/usr/include/qt5/QtCore/qobject.h: In substitution of ‘template<class Func1, class Func2> static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = const char*; Func2 = const char*]’:
finddialog.cpp:23:61:   required from here
/usr/include/qt5/QtCore/qobject.h:215:43: error: no type named ‘Object’ in ‘struct QtPrivate::FunctionPointer<const char*>’
/usr/include/qt5/QtCore/qobject.h:245:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<((int)(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2)
             connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
             ^
/usr/include/qt5/QtCore/qobject.h:245:13: note:   template argument deduction/substitution failed:
finddialog.cpp:23:61: note:   candidate expects 3 arguments, 4 provided
  connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
                                                             ^
In file included from /usr/include/qt5/QtCore/qabstractanimation.h:45:0,
                 from /usr/include/qt5/QtCore/QtCore:4,
                 from /usr/include/qt5/QtGui/QtGui:4,
                 from finddialog.cpp:1:
/usr/include/qt5/QtCore/qobject.h:268:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2)
             connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
             ^
/usr/include/qt5/QtCore/qobject.h:268:13: note:   template argument deduction/substitution failed:
finddialog.cpp:23:61: note:   candidate expects 3 arguments, 4 provided
  connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
                                                             ^
finddialog.cpp:25:2: error: ‘QHBoxLayout’ was not declared in this scope
  QHBoxLayout *topLeftLayout = new QHBoxLayout;
  ^
finddialog.cpp:25:15: error: ‘topLeftLayout’ was not declared in this scope
  QHBoxLayout *topLeftLayout = new QHBoxLayout;
               ^
finddialog.cpp:25:35: error: expected type-specifier before ‘QHBoxLayout’
  QHBoxLayout *topLeftLayout = new QHBoxLayout;
                                   ^
finddialog.cpp:25:35: error: expected ‘;’ before ‘QHBoxLayout’
finddialog.cpp:29:2: error: ‘QVBoxLayout’ was not declared in this scope
  QVBoxLayout *leftLayout = new QVBoxLayout;
  ^
finddialog.cpp:29:15: error: ‘leftLayout’ was not declared in this scope
  QVBoxLayout *leftLayout = new QVBoxLayout;
               ^
finddialog.cpp:29:32: error: expected type-specifier before ‘QVBoxLayout’
  QVBoxLayout *leftLayout = new QVBoxLayout;
                                ^
finddialog.cpp:29:32: error: expected ‘;’ before ‘QVBoxLayout’
finddialog.cpp:34:15: error: ‘rightLayout’ was not declared in this scope
  QVBoxLayout *rightLayout = new QVBoxLayout;
               ^
finddialog.cpp:34:33: error: expected type-specifier before ‘QVBoxLayout’
  QVBoxLayout *rightLayout = new QVBoxLayout;
                                 ^
finddialog.cpp:34:33: error: expected ‘;’ before ‘QVBoxLayout’
finddialog.cpp:39:15: error: ‘mainLayout’ was not declared in this scope
  QHBoxLayout *mainLayout = new QHBoxLayout;
               ^
finddialog.cpp:39:32: error: expected type-specifier before ‘QHBoxLayout’
  QHBoxLayout *mainLayout = new QHBoxLayout;
                                ^
finddialog.cpp:39:32: error: expected ‘;’ before ‘QHBoxLayout’
finddialog.cpp: In member function ‘void FindDialog::findClicked()’:
finddialog.cpp:50:25: error: invalid use of incomplete type ‘class QLineEdit’
  QString text = lineEdit->text();
                         ^
In file included from finddialog.cpp:3:0:
finddialog.h:8:7: error: forward declaration of ‘class QLineEdit’
 class QLineEdit;
       ^
finddialog.cpp:51:39: error: invalid use of incomplete type ‘class QCheckbox’
  Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseSensitivity
                                       ^
In file included from finddialog.cpp:3:0:
finddialog.h:6:7: error: forward declaration of ‘class QCheckbox’
 class QCheckbox;
       ^
finddialog.cpp:52:17: error: expected primary-expression before ‘:’ token
                 : Qt::CaseInsensitive;
                 ^
finddialog.cpp:53:21: error: invalid use of incomplete type ‘class QCheckbox’
  if(backwardCheckBox->isChecked()) {
                     ^
In file included from finddialog.cpp:3:0:
finddialog.h:6:7: error: forward declaration of ‘class QCheckbox’
 class QCheckbox;
       ^
finddialog.cpp: In member function ‘void FindDialog::enableFindButton(const QString&)’:
finddialog.cpp:62:12: error: invalid use of incomplete type ‘class QPushButton’
  findButton->setEnabled(!text.isEmpty());
            ^
In file included from /usr/include/qt5/QtWidgets/QDialog:1:0,
                 from finddialog.h:4,
                 from finddialog.cpp:3:
/usr/include/qt5/QtWidgets/qdialog.h:52:7: error: forward declaration of ‘class QPushButton’
 class QPushButton;
       ^
make: *** [finddialog.o] Error 1

5 个答案:

答案 0 :(得分:13)

错误应该来自您的.pro文件,因为您使用的是Qt5,您应该包括:

QT += widgets

更改

的所有实例
#include <QtGui>

#include <QtWidgets>

但是包含你需要的文件而不是整个QtGui或QtWidgets要好得多。

答案 1 :(得分:6)

我正在读同一本书。需要修复两件事才能使此示例正常工作。

  1. findDialog.h头文件中的'class'前向声明不起作用,因此无法找到QLabel等的构造函数。用相应的#include替换每个类,如下所示。 (在finddialog.h文件中不需要QHBoxLayout和QVBoxLayout,但为方便起见,我也移动了所有必需的包含在同一个地方)。

    #include <QDialog>
    #include <QCheckBox>    //class QCheckBox;  
    #include <QLabel>       //class QLabel;     
    #include <QLineEdit>    //class QLineEdit;  
    #include <QPushButton>  //class QPushButton; 
    #include <QHBoxLayout>  //in the finddialog.cpp
    #include <QVBoxLayout>  //in the finddialog.cpp
    
  2. 将.pro文件编辑为:

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET   = find 
    
    TEMPLATE = app
    
    HEADERS  = finddialog.h
    
    SOURCES  = finddialog.cpp \
               main.cpp
    
  3. 删除所有旧的makefile和find.pro.user并重建项目。

答案 2 :(得分:3)

从Qt4移动时,您需要更改许多项目。以下是根据我的经验(来自http://www.gpupowered.org/node/23)的列表。无论如何,这不是一个完整的清单。

  1. QtGui中QWidget定义的错误。如已建议的那样在.pro文件中添加Qt + =小部件。

  2. 有些像#include“QGraphicsItem”,需要QtWidgets / QGraphicsItem,QtWidgets / QVBoxLayout

  3. QGtring :: toAscii()== xgxperfserver.cpp中的QString :: toLatin1()

  4. Qt + =需要小部件,以避免链接所有小部件的错误

  5. Project ERROR:QT中的未知模块:svg == svg在Qt中不是默认值,需要qtsvg

  6. QApplication == QtWidgets / QApplication

  7. 需要明确声明“QtWidgets / QGraphicsProxyWidget”

  8. 包含要明确声明的“QtWidgets / QGraphicsDropShadowEffect”

  9. 包含要明确声明的“QDebug”

  10. 如果项目包含.ui文件,并且需要ui_mainwindow.h,还需要添加QT + = widgets,以便调用uic来生成ui文件

  11. 添加QtWidgets,#include“QtWidgets / QGraphicsEffect”

  12. 添加QtWidgets,#include“QtWidgets / QGraphicsView”

  13. 包括“QtWidgets / QPushButton”

  14. QGraphicsItem :: Scale变为QGraphicsItem :: setScale

  15. QApplication :: sendEvent成为QCoreApplication :: sendEvent

  16. QGraphicsDropShadowEffect变为QtWidgets / QGraphicsDropShadowEffect

答案 3 :(得分:1)

我也在读同一本书。问题来自Qt的版本。这本书是为Qt4编写的,当你尝试使用Qt5时。解决问题的最简单方法是更改​​以下行。

FindDialog.pro 中添加:

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

并在 FindDialog.cpp 中更改#include <QtGui>行:

#include <QtWidgets>

您不需要包含更多内容,现在应该编译时没有错误。有关它的更多信息,请查看有关transition from Qt4 to Qt5

的Qt文档

答案 4 :(得分:0)

对我来说,qmake -v举报QMake version 3.0Qt version 5.3.0,其工作原理如下:

1)将这两行添加到find.pro:

QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

2)在find.h中保留前向声明,并在find.cpp中使用下面的包含:

#include <QCheckBox>
#include <QLineEdit>
#include <QLabel>
#include <QPushButtons>

#include <QHBoxLayout>
#include <QVBoxLayout>