2017-07-15 533 views
0

Qt的新功能。 对于一本书中的“C++ GUI Qt 4”,在第二章中看到一段代码,书中没有包括这几个相关的头文件(例如),但是使用了一些前置声明,这个是一些更快的汇编。可是我错了编译: “无效的使用不完全类型的:”预先声明并在Qt中包含头文件/ bese

finddialog.h

#ifndef FINDDIALOG_H 
#define FINDDIALOG_H 
#include <QDialog> 
#include <QHBoxLayout> 

//#include <QLabel> 
//#include <QCheckBox> 
//#include <QLineEdit> 
//#include <QPushButton> 

class QLabel; 
class QCheckBox; 
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_H 

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("seach &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 QSting &))); 
    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::CaseSensitive:Qt::CaseInsensitive; 
    if(backwardCheckBox->isChecked()) 
    { 
     emit findPrevious(text,cs); 

    } 
    else 
    { 
     emit findNext(text,cs); 
    } 

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

enter image description here

+1

在你的cpp文件中,你需要包含, ......基本上你所有的头部注释掉的'Qt'头文件都会将这些头文件包含在你的cpp文件中。 – drescherjm

+0

你的意思是添加头文件(#include )还是预声明(QLabel类)? –

+0

我只懂英语,也许有点西班牙语。抱歉。 – drescherjm

回答

0

注意,默认类型由Qt定义被放置在一个命名空间中,但是一个头文件会执行一个using namespace指令,所以你大多不需要担心它。但这意味着一个普通的旧前向声明不符合正确的名称。转发申报属于Qt库类的正确方法是:

QT_FORWARD_DECLARE_CLASS(QLabel) 
QT_FORWARD_DECLARE_CLASS(QCheckBox) 
QT_FORWARD_DECLARE_CLASS(QLineEdit) 
QT_FORWARD_DECLARE_CLASS(QPushButton) 

正如评论暗示,直到它已经看到,编译器不会让你做new Typeptr->member,或其他各种东西该类的完整定义,而不仅仅是一个前向声明。因此,有没有需要回避的包括在* .cpp文件:

#include <QLabel> 
#include <QCheckBox> 
#include <QLineEdit> 
#include <QPushButton> 

现在你的一个* .cpp文件有它需要的所有的依赖关系,再加上其他* .cpp文件,其中包括您的* .h文件中不要”不一定需要花费额外的编译时间来阅读这些标题并解析内容。

+0

我将“class QLabel”改为“QT_FORWARD_DECLARE_CLASS (QLabel)“,但也有同样的错误。 –

+0

适用于我这些变化。你会得到什么确切的错误? – aschepler

+0

我相信他预计'QT_FORWARD_DECLARE_CLASS(QLabel)'将不再需要在cpp文件中使用'#include '。 – drescherjm