完美解決QT?QGraphicsView提升到QChartView報錯的問題
QT QGraphicsView 提升到 QChartView報錯 解決方案
本文主要描述,使用QT提供的QChartView來繪制圖表,提升QGraphicsView控件繼承QChartView后,然后將QGraphicsView提升到我們自己寫的類,怎么才能確保提升后編譯不報錯.
[問題描述]
使用QGraphicsView顯示圖表的時候,我們需要將它提升為QChartView.但提升后再此運(yùn)行一般會發(fā)生編譯報錯,錯誤發(fā)生在自動生成的UI頭文件中.如下圖:
使用QT提供的QChartView,提升QGraphicsView后遇到的問題解決方案
[解決方案]
臨時方案(主要是修改ui_xxxx.h文件)終極解決方案(針對網(wǎng)上好多方案都是修改ui_xxx.h文件,然后重新編譯后又報錯,又要修改)
[問題分析]
我們來分析一下這個問題:
- 錯誤提示說 QChartView does not name a type.
- 疑問一: 為什么說 不能命名成一個類型呢?
- 疑問二: ui_mainwindow.h文件中已經(jīng)有qchartview.h頭文件了,不認(rèn)識QChartView?
帶著疑問,我們?nèi)タ聪聁chartview.h的源代碼:
大概理解或者猜一下,開始一個命名空間?
點擊進(jìn)去我們再看看這個QT_CHARTS_BEGIN_NAMESPACE是個什么?
看到這個的話,應(yīng)該都比較清楚了,這是給QChartView 加了一個命名空間.
所以我們在使用的時候要把命名空間帶上.
清楚這個了,我們開始看怎么解決這個問題.
[方案描述]
既然ui_xxx.h文件報錯,那么我們先修改一下這個文件,讓他不報這個錯,看看是否能解決問題.
第一種: 將 QtCharts這個命名空間加到我們的代碼上.
修改前
#include <QtCore/QVariant> #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QMenuBar> #include <QtWidgets/QStatusBar> #include <QtWidgets/QWidget> #include <qchartview.h> QT_BEGIN_NAMESPACE class Ui_MainWindow { public: QWidget *centralwidget; QChartView *graphicsView; // 修改前 ... void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) MainWindow->setObjectName(QString::fromUtf8("MainWindow")); MainWindow->resize(800, 600); centralwidget = new QWidget(MainWindow); centralwidget->setObjectName(QString::fromUtf8("centralwidget")); graphicsView = new QChartView(centralwidget);// 修改前 ... }
修改后
#include <QtCore/QVariant> #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QMenuBar> #include <QtWidgets/QStatusBar> #include <QtWidgets/QWidget> #include <qchartview.h> QT_BEGIN_NAMESPACE class Ui_MainWindow { public: QWidget *centralwidget; QtCharts::QChartView *graphicsView; //修改后 ... void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) MainWindow->setObjectName(QString::fromUtf8("MainWindow")); MainWindow->resize(800, 600); centralwidget = new QWidget(MainWindow); centralwidget->setObjectName(QString::fromUtf8("centralwidget")); graphicsView = new QtCharts::QChartView(centralwidget); // 修改后 ...
修改后,代碼編譯通過,運(yùn)行結(jié)果如下:
第二種: 在ui_xxx.h文件中把命名空間加上:using namespace QtCharts; 或者直接使用 QT已經(jīng)定義好的:QT_CHARTS_USE_NAMESPACE
#include <QtWidgets/QStatusBar> #include <QtWidgets/QWidget> #include <qchartview.h> //using namespace QtCharts; QT_CHARTS_USE_NAMESPACE QT_BEGIN_NAMESPACE
編譯運(yùn)行,也能正常運(yùn)行.
繼續(xù)思考:
這個ui_xxx.h文件是自動生成的,如果重新編譯的話,我們的修改都被覆蓋掉了,我們難道再去修改? 顯然不是最佳方案.
注意到ui_xxx.h的文件注釋: WARNING! All changes made in this file will be lost when recompiling UI file!
/********************************************************************************
** Form generated from reading UI file ‘mainwindow.ui’
**
** Created by: Qt User Interface Compiler version 5.15.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
所以: 修改ui_xxx.h文件顯然不合適.
那么我們需要將這個命名空間在ui_xxx.h使用QChartView之前先using.
1.將QT_CHARTS_USE_NAMESPACE 直接添加到 mianwindow.h文件里面.如下:
2.編譯通過,運(yùn)行得到我們想要的結(jié)果將 QT_CHARTS_USE_NAMESPACE 放到mainwindow.cpp里面.
同樣的錯誤又出現(xiàn)了
難道不能放到 mainwidow.cpp里面?
既然這個namespace是在ui_xxx.h文件中用呢,那我把這定義到前面不就可以嗎?
修改后,再一次編譯運(yùn)行: 成功,如下圖:
至于命名空間,大家根據(jù)自己習(xí)慣和情況放到合適的地方就行.
繼承QChartView, 提升QGraphicsView控件
先看問題: 如下圖,我們編譯會報錯,但報錯的提示信息和之前的是不一樣的.
提示信息:ui_mainwindow.h:18: error: ctqchartview.h: No such file or directory
提示是說找不到這個文件或文件夾. 怎么理解呢?
意思就是這個頭文件的路徑不對了.
看下我們的代碼,ctqchartview是在CtChartView這個目錄下的. 那我們在ui_xxx.h文件中修改下路徑
修改路徑后,成功編譯運(yùn)行如下:
修改后,是可以編譯運(yùn)行了,但我們還是會遇到之前的問題,重新編譯后,這塊還是會報錯,我們還要修改再編譯運(yùn)行.
那么有沒有 一個修改一次后面就不用再改的方案呢?
答案是肯定的.
方案一:
思考一下,我們ui_xxx.h文件中的 <ctqchartview.h> 是從那來的?
是不是我們在點擊提升的時候,我們自己填的呢?
如下圖: 這個 頭文件不就是這個嗎?
所以ui_xxx.h文件中會生成一個 #include “ctqchartview.h” 這句代碼.
但引入進(jìn)去后會提示找不到, 那我們把路徑加上去,不就可以了嗎? 如下圖,點擊添加
直接編譯運(yùn)行: 成功,如下圖:
方案二:
我們的CtQChartView是繼承QChartView的, 那我們能不能
在提升的時候,類寫CtQChartView, 頭文件 qchartview.h 呢?
如下圖:
這樣提升后,我們編譯試試: 報錯,看提示應(yīng)該是沒找到這個類.
解決: 在mainwindow.h文件中我們引入#include “CtChartView/ctqchartview.h” 這個頭文件,再此編譯運(yùn)行.
結(jié)果如下圖:
接著繼續(xù), 看ui_xxx.h文件,發(fā)現(xiàn)聲明: CtQChartView *graphicsView;
定義:graphicsView = new CtQChartView(centralwidget);
都沒用qchartview.h文件呀, 那把這個頭文件刪除掉,能編譯成功嗎?
一樣可以成功,那這代表什么呢?
猜想一下,那我們提升的時候,只寫一個類,然后在mainwindow.h文件中include的這個類的頭文件,是不是也可以呢?
如下圖:如果不填頭文件的話,不讓添加.
再思考下,那我給這個頭文件寫一個ui_xxx.h中已經(jīng)存在的頭文件,可行嗎? 或者我把這個頭文件寫成QObject可行嗎?
例如我填一個 QtWidgets/QMenuBar. 編譯運(yùn)行.可成功.
基于以上,我們是不是可以思考一下結(jié)論:
- 提升QGraphicsView 的類,只要在 ui_xxx.h 頭文件前引用就可以.
- 在xxx.ui文件中提升QGraphicsView的時候,只要正確填寫我們希望提升的類名就可以了. 當(dāng)然頭文件也需要填寫一個正確的.
到此這篇關(guān)于完美解決QT QGraphicsView提升到QChartView報錯的問題的文章就介紹到這了,更多相關(guān)QChartView報錯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ std::initializer_list 實現(xiàn)原理解析及遇到問題
這篇文章主要介紹了C++ std::initializer_list 實現(xiàn)原理勘誤,本文通過源碼解析給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02C++可調(diào)用對象callable object深入分析
所謂的callable object,表示可以被某種方式調(diào)用其某些函數(shù)的對象。它可以是:一個函數(shù)、一個指向成員函數(shù)的指針、一個函數(shù)對象,該對象擁有operator()、一個lambda表達(dá)式,嚴(yán)格的說它是一種函數(shù)對象2022-08-08