
我按照書上說的做一個簡單的銷售車輛管理的界面,只做了一部分,編譯報錯invalid use of incomplete type 'class Ui :: Widget',請高手幫忙看看,應該不復雜,我是新手。卡在這里了。多謝多謝!
widget.h
-----------------------
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMenuBar>
#include <QMainWindow>
namespace Ui {
class Widget;
}
class Widget : public QMainWindow
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QMenu *salesMgtMenu;
QMenu *pwdMenu;
QAction *salesMgtAction;
QAction *chartAction;
QAction *quitAction;
private slots:
void on_salesMgtMenu_click();
void on_chartMenu_click();
void on_quitMenu_click();
private:
Ui::Widget *ui;
void createMenuBar();
};
void Widget::createMenuBar()
{
salesMgtAction = new QAction (tr("品牌車管理"),this);
chartAction = new QAction (tr("銷售統計圖表"),this);
quitAction = new QAction (tr("exit"),this);
salesMgtMenu = menuBar()->addMenu(tr("銷售管理"));
salesMgtMenu ->addAction(salesMgtAction);
salesMgtMenu ->addAction(chartAction);
salesMgtMenu ->addAction(quitAction);
pwdMenu = menuBar()->addMenu(tr("修改密碼"));
connect (salesMgtAction,SIGNAL(triggered()),this, SLOT(on_salesMgtMenu_click()));
connect (chartAction,SIGNAL(triggered()),this, SLOT(on_chartMenu_click()));
connect (quitAction,SIGNAL(triggered()),this, SLOT(on_quitMenu_click()));
}
void Widget::on_salesMgtMenu_click()
{
ui->stackedWidget->setCurrentIndex(0); //此處報錯 invalid use of incomplete type 'class Ui :: Widget'
}
void Widget::on_chartMenu_click()
{
ui->stackedWidget->setCurrentIndex(1); //此處報錯 invalid use of incomplete type 'class Ui :: Widget'
}
void Widget::on_quitMenu_click()
{
this->close();
}
#endif // WIDGET_H
-------------------------------------------
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
createMenuBar();
}
Widget::~Widget()
{
delete ui;
}
---------------------------------------
uj5u.com熱心網友回復:
你的這個視窗是通過QtDesigner拖拽出來的吧,你沒有把這個檔案加載進去。假設你設計的這個視窗名稱為mywidget,檔案名稱為mywidget.ui,那你需要在widget.h檔案中添加#include "ui_mywidget.h"。而且不太建議你用namespace的方式,我一般按照下面這個用法使用ui檔案widget.h
-----------------------
#ifndef WIDGET_H
#define WIDGET_H
//參考的頭檔案
#include "ui_mywidget.h"
class Widget : public QMainWindow, public Ui_Mywidget
{
Q_OBJECT
public:
..........
Ui::Mywidget *ui;
..........
}
#endif
uj5u.com熱心網友回復:
你好,謝謝你的回答。我按照你建議的,改成如下, 運行后開始的錯誤沒有了,但出來了新的報錯:
multiple definition of ' Widget :: Widget::createMenuBar()"
multiple definition of ' Widget::on_salesMgtMenu_click()"
multiple definition of ' Widget::on_quitMenu_click()"
我后來洗掉了namespace, 改到了public定義UI,也是一樣。 多謝指教!
widget.h
-----------------------------
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMenuBar>
#include <QMainWindow>
#include "ui_widget.h"
namespace Ui {
class Widget;
}
class Widget : public QMainWindow
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QMenu *salesMgtMenu;
QMenu *pwdMenu;
QAction *salesMgtAction;
QAction *chartAction;
QAction *quitAction;
private slots:
void on_salesMgtMenu_click();
void on_chartMenu_click();
void on_quitMenu_click();
private:
Ui::Widget *ui;
void createMenuBar();
};
void Widget::createMenuBar()
{
salesMgtAction = new QAction (tr("品牌車管理"),this);
chartAction = new QAction (tr("銷售統計圖表"),this);
quitAction = new QAction (tr("exit"),this);
salesMgtMenu = menuBar()->addMenu(tr("銷售管理"));
salesMgtMenu ->addAction(salesMgtAction);
salesMgtMenu ->addAction(chartAction);
salesMgtMenu ->addAction(quitAction);
pwdMenu = menuBar()->addMenu(tr("修改密碼"));
connect (salesMgtAction,SIGNAL(triggered()),this, SLOT(on_salesMgtMenu_click()));
connect (chartAction,SIGNAL(triggered()),this, SLOT(on_chartMenu_click()));
connect (quitAction,SIGNAL(triggered()),this, SLOT(on_quitMenu_click()));
}
void Widget::on_salesMgtMenu_click()
{
ui->stackedWidget->setCurrentIndex(0);
}
void Widget::on_chartMenu_click()
{
ui->stackedWidget->setCurrentIndex(1);
}
void Widget::on_quitMenu_click()
{
this->close();
}
#endif // WIDGET_H
uj5u.com熱心網友回復:
你把所有實作在widget.h中的成員函式挪到cpp里就可以了。因為你在頭檔案里用了Ui::Widget *ui;而在頭檔案里這個成員變數只是前向宣告了,你的widget.h中因為沒有包含ui_widget.h所以編譯報錯。而一般我們在widget.h中是不推薦包含ui_widget.h的uj5u.com熱心網友回復:
用namespace的方式是Qt預設自動幫你做的,這種做法是Qt推薦的。相反,盡量不要用多繼承。你的問題也不是因為namespace而產生的。我估計你對c++編程還是比較生疏的。你出的這個問題其實是c++的問題,和Qt沒多大關系uj5u.com熱心網友回復:
你說的很對,我把這幾個成員函式挪到CPP里面就運行成功了。是不是因為CPP里面有#include "ui_widget.h"這句話?但是我在widget.h里面后來也包含了#include "ui_widget.h"這句話,為啥運行還是出錯,必須挪到CPP里面就可以了呢?
多謝!
是的,我不太熟悉C++, 學過,但是理解不深。
uj5u.com熱心網友回復:
沒事,誰都是一步步學起來的。你說的理解對了。QT會根據你的UI檔案自動生成一個ui_xxx.h頭檔案。所以一般來說,c++有一種設計模式:為了減少重復參考,加快編譯速度,頭檔案里盡量不要包含其他頭檔案。頭檔案包含能放在cpp里的都放在cpp。Qt預設也是幫你把ui_xxx.h包含放在cpp里了。之所以你把ui_xxx.h放在頭檔案里還報錯,那是因為你這么做就發生重復定義了。你得把頭檔案里的 namespace Ui {xxx}你不分刪掉才會正確
uj5u.com熱心網友回復:
非常感謝!牛人就是一下子解決了我的問題。:)轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/129117.html
標籤:Qt
