2017-07-15 536 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