C++ Qt 错误:无效使用不完整类型 'class QLabel'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21783123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Qt error: invalid use of incomplete type 'class QLabel'
提问by Hell Man
I'm trying to compile the following program using QtCreater but I get a lots of errors in this program. I got this program from a book and I'm not able to figure out where the error is. Can someone help debug this program.
我正在尝试使用 QtCreater 编译以下程序,但在此程序中出现很多错误。我从一本书中得到了这个程序,但我无法弄清楚错误在哪里。有人可以帮助调试这个程序。
Here is the FindDialog.h
这是 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
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();
}
The errors I get are the following:
我得到的错误如下:
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
回答by Kirell
The error should come from your .pro file since your are using Qt5 you should include:
错误应该来自您的 .pro 文件,因为您使用的是 Qt5,您应该包括:
QT += widgets
Change all instances of
更改所有实例
#include <QtGui>
to
到
#include <QtWidgets>
But it is much better to include the file you need instead of the whole QtGui or QtWidgets.
但是最好包含您需要的文件而不是整个 QtGui 或 QtWidgets。
回答by dalilander
I'm reading the same book. There are 2 things that need to be fixed to get this sample to work.
我在看同一本书。有两件事需要修复才能使此示例正常工作。
The 'class' forward declarations in the findDialog.h header file do not work so no constructor for QLabel, etc. can be found. Replace each class with the corresponding #include as follows. (The QHBoxLayout and QVBoxLayout are not needed in the finddialog.h file but for convenience I moved those too so that all required includes are in the same place).
#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
Edit the .pro file to this:
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = find TEMPLATE = app HEADERS = finddialog.h SOURCES = finddialog.cpp \ main.cpp
Delete all the old makefiles and find.pro.user and rebuild the project.
findDialog.h 头文件中的“类”前向声明不起作用,因此找不到 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
将 .pro 文件编辑为:
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = find TEMPLATE = app HEADERS = finddialog.h SOURCES = finddialog.cpp \ main.cpp
删除所有旧的 makefile 和 find.pro.user 并重建项目。
回答by Prabindh
You need to change many items when moving from Qt4. Below is a list based on my experience (from http://www.gpupowered.org/node/23). This is not a complete list by any means.
从 Qt4 迁移时,您需要更改许多项目。以下是基于我的经验的列表(来自http://www.gpupowered.org/node/23)。无论如何,这不是一个完整的列表。
Errors in QtGui for QWidget definition. Add Qt += widgets in the .pro file as already suggested.
Some like #include " QGraphicsItem ", need QtWidgets/QGraphicsItem, QtWidgets/QVBoxLayout
QString::toAscii() == QString::toLatin1() in xgxperfserver.cpp
Qt += widgets needed, to avoid linking errors for all widgets
Project ERROR: Unknown module(s) in QT: svg == svg is not default in Qt, needs qtsvg
QApplication == QtWidgets/QApplication
" QtWidgets/QGraphicsProxyWidget " needs to be declared explicitly
include " QtWidgets/QGraphicsDropShadowEffect " to be declared explicitly
include " QDebug " to be declared explicitly
If project includes .ui files, and needs the ui_mainwindow.h, also need to add QT += widgets, to get uic to be called to generate ui files
Add QtWidgets, #include " QtWidgets/QGraphicsEffect "
Add QtWidgets, #include " QtWidgets/QGraphicsView "
include " QtWidgets/QPushButton "
QGraphicsItem::Scale becomes QGraphicsItem::setScale
QApplication::sendEvent becomes QCoreApplication::sendEvent
QGraphicsDropShadowEffect becomes QtWidgets/QGraphicsDropShadowEffect
QWidget 定义的 QtGui 中的错误。如已建议的那样,在 .pro 文件中添加 Qt += 小部件。
有些像#include " QGraphicsItem ",需要QtWidgets/QGraphicsItem、QtWidgets/QVBoxLayout
xgxperfserver.cpp 中的 QString::toAscii() == QString::toLatin1()
需要 Qt += 小部件,以避免所有小部件的链接错误
项目错误:QT 中的未知模块:svg == svg 在 Qt 中不是默认值,需要 qtsvg
QApplication == QtWidgets/QApplication
“ QtWidgets/QGraphicsProxyWidget ”需要明确声明
包括要显式声明的“ QtWidgets/QGraphicsDropShadowEffect ”
包括要显式声明的“ QDebug ”
如果项目包含.ui文件,并且需要ui_mainwindow.h,还需要添加QT+=widgets,才能调用uic生成ui文件
添加 QtWidgets, #include " QtWidgets/QGraphicsEffect "
添加 QtWidgets, #include " QtWidgets/QGraphicsView "
包括“QtWidgets/QPushButton”
QGraphicsItem::Scale 变成 QGraphicsItem::setScale
QApplication::sendEvent 变成 QCoreApplication::sendEvent
QGraphicsDropShadowEffect 变成 QtWidgets/QGraphicsDropShadowEffect
回答by Mario García
I am also reading the same book. The problem comes from the versions of Qt. The book is written for Qt4, while you are trying to use Qt5. The easiest way to solve it is by changing the following lines.
我也在读同一本书。问题来自 Qt 的版本。这本书是为 Qt4 编写的,而您正在尝试使用 Qt5。解决它的最简单方法是更改以下几行。
In FindDialog.proadd:
在FindDialog.pro 中添加:
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
and in FindDialog.cppchange #include <QtGui>
for the line:
并在FindDialog.cpp 中更改#include <QtGui>
该行:
#include <QtWidgets>
You don't need to include more and it should compile without errors now. For more info about it, check the Qt documentation about the transition from Qt4 to Qt5.
您不需要包含更多内容,它现在应该可以无误地编译。有关它的更多信息,请查看有关从 Qt4 到 Qt5的转换的 Qt 文档。
回答by rturrado
For me, with qmake -v
reporting QMake version 3.0
and Qt version 5.3.0
, it worked the following:
对我来说,通过qmake -v
报告QMake version 3.0
和Qt version 5.3.0
,它的作用如下:
1) Add these two lines to find.pro:
1)在find.pro中加入这两行:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
2) Keep the forward declarations in find.h, and use the includes below in find.cpp:
2) 在 find.h 中保留前向声明,并在 find.cpp 中使用以下包含:
#include <QCheckBox>
#include <QLineEdit>
#include <QLabel>
#include <QPushButtons>
#include <QHBoxLayout>
#include <QVBoxLayout>