本文共 11010 字,大约阅读时间需要 36 分钟。
创建Migration目录,在目录下创建main.cpp文件:
#include#include int main(int argc, char *argv[]){ QApplication app(argc, argv); QLabel label(QString("Hello Qt%1!").arg(int(QT_VERSION >> 16))); label.setAlignment(Qt::AlignCenter); label.resize(200, 100); label.show(); return app.exec();}
编写兼容Qt4和Qt5的CMake宏,QtMigration.cmake文件如下:
# 定义宏QT_USE_MODULESmacro(QT_USE_MODULES _target) # Enable AUTOMOC set_target_properties(${_target} PROPERTIES AUTOMOC TRUE) # Local variables set(_modules_qt4) set(_modules_qt5) # Prepare modules foreach(_module ${ARGN}) list(APPEND _modules_qt4 Qt${_module}) list(APPEND _modules_qt5 ${_module}) if(_module MATCHES "Gui") list(APPEND _modules_qt5 "Widgets") endif(_module MATCHES "Gui") endforeach(_module ${ARGN}) list(REMOVE_DUPLICATES _modules_qt4) list(REMOVE_DUPLICATES _modules_qt5) # Find Qt libraries find_package(Qt5 QUIET COMPONENTS ${_modules_qt5}) if(Qt5_FOUND) qt5_use_modules(${_target} ${_modules_qt5}) else(Qt5_FOUND) find_package(Qt4 QUIET COMPONENTS ${_modules_qt4}) if(Qt4_FOUND OR QT4_FOUND) include(${QT_USE_FILE}) include_directories(${QT_INCLUDES}) add_definitions(${QT_DEFINITIONS}) target_link_libraries(${_target} ${QT_LIBRARIES}) endif(Qt4_FOUND OR QT4_FOUND) endif(Qt5_FOUND)endmacro(QT_USE_MODULES)
编写工程CMakeLists.txt文件,内容如下:
cmake_minimum_required(VERSION 2.8.9)project(Migration)list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})aux_source_directory(. SRC_LIST)add_executable(${PROJECT_NAME} ${SRC_LIST})include(QtMigration.cmake)QT_USE_MODULES(${PROJECT_NAME} Core Gui)
Migration工程内创建build目录,进入build目录,进行构建。
cmake ..make
对于Qt4,使用FIND_PACKAGE后,会生成有效的Qt4_FOUND,QT_USE_FILE,QT_INCLUDES,QT_LIBRARIES变量。
FIND_PACKAGE(Qt4 REQUIRED Core Gui)if(Qt4_FOUND) INCLUDE(${QT_USE_FILE}) INCLUDE_DIRECTORIES(${QT_INCLUDES}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${QT_LIBRARIES})endif()
对于Qt5,使用FIND_PACKAGE后,会生成有效的Qt5_FOUND,Qt5Core_INCLUDE_DIRS,Qt5Xml_INCLUDE_DIRS,Qt5Gui_INCLUDE_DIRS,Qt5Widgets_INCLUDE_DIRS,Qt5OpenGL_INCLUDE_DIRS,Qt5Widgets_LIBRARIES,Qt5Core_LIBRARIES,Qt5Gui_LIBRARIES,Qt5Xml_LIBRARIES,Qt5OpenGL_LIBRARIES等相应模块的变量。
FIND_PACKAGE(Qt5 REQUIRED Core Gui Widgets OpenGL Xml)if(Qt5_FOUND) INCLUDE_DIRECTORIES(${Qt5Core_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5OpenGL_INCLUDE_DIRS}) #定义QT_LIBRARIES SET(QT_LIBRARIES ${Qt5Widgets_LIBRARIES} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Xml_LIBRARIES} ${Qt5OpenGL_LIBRARIES}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${QT_LIBRARIES})endif(Qt5_FOUND)
开启MOC支持
set(CMAKE_AUTOMOC ON)
开启RCC支持set(CMAKE_AUTORCC ON)
开启UIC支持set(CMAKE_AUTOUIC ON)
设置Qt安装目录:set(CMAKE_PREFIX_PATH "Qt to path ") //bin lib include目录层
选择新建工程,创建一个Plain C++ Application。
选择使用CMake构建工程:选择使用的Qt Kits版本:选择菜单栏新建文件按钮,选择Files and Classes,C++ Class。
填写创建C++类的名称BarModelMapperChartWidget:选择创建类文件所在位置,点击浏览按钮:点击新建目录按钮创建ChartWidget目录,选择ChartWidget。BarModelMapperChartWidget.h文件如下:#ifndef BARMODELMAPPERCHARTWIDGET_H#define BARMODELMAPPERCHARTWIDGET_H#include#include #include #include #include #include #include #include #include #include #include QT_CHARTS_USE_NAMESPACE/** * @brief 柱状图ModelMapper报表界面类 */class BarModelMapperChartWidget : public QWidget{ Q_OBJECTpublic: explicit BarModelMapperChartWidget(QWidget *parent = NULL); /** * @brief 初始化ModelMapper * @param model */ void initModelMapper(QAbstractTableModel* model);private: QChart* m_chart;//报表组件 QChartView* m_chartView;//报表视图组件};#endif // BARMODELMAPPERCHARTWIDGET_H
BarModelMapperChartWidget.cpp文件如下:
#include "BarModelMapperChartWidget.h"BarModelMapperChartWidget::BarModelMapperChartWidget(QWidget *parent) : QWidget(parent){ m_chart = new QChart; m_chart->setAnimationOptions(QChart::AllAnimations); m_chartView = new QChartView(m_chart); m_chartView->setRenderHint(QPainter::Antialiasing); QHBoxLayout* layout = new QHBoxLayout; layout->addWidget(m_chartView); setLayout(layout);}void BarModelMapperChartWidget::initModelMapper(QAbstractTableModel *model){ QBarSeries *series = new QBarSeries; int first = 3; int count = 5; QVBarModelMapper *mapper = new QVBarModelMapper(this); mapper->setFirstBarSetColumn(1); mapper->setLastBarSetColumn(4); mapper->setFirstRow(first); mapper->setRowCount(count); // 设置mapper的数据集对象 mapper->setSeries(series); // 设置mapper对应的数据Model mapper->setModel(model); m_chart->addSeries(series); QStringList categories; categories << "April" << "May" << "June" << "July" << "August"; QBarCategoryAxis *axis = new QBarCategoryAxis(); axis->append(categories); m_chart->createDefaultAxes(); m_chart->setAxisX(axis, series);}
创建TableModel类:
TableModel.h文件如下:#ifndef TABLEMODEL_H#define TABLEMODEL_H#include#include #include #include #include #include #include /** * @brief 数据模型 */class TableModel : public QAbstractTableModel{ Q_OBJECTpublic: explicit TableModel(QObject *parent = 0); virtual ~TableModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); Qt::ItemFlags flags(const QModelIndex &index) const; /** * @brief 生成数据 */ void generateData();private slots: /** * @brief 定时器超时信号的槽函数 */ void onGenerateData();private: QList * > m_data;//模型数据容器 int m_columnCount;//列数 int m_rowCount;//行数 QTimer timer;//定时器};#endif // TABLEMODEL_H
TableModel.cpp文件如下:
#include "TableModel.h"TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent){ m_columnCount = 6; m_rowCount = 12; // 创建数据容器并初始化 for (int i = 0; i < m_rowCount; i++) { QVector* dataVec = new QVector (m_columnCount); for (int k = 0; k < dataVec->size(); k++) { dataVec->replace(k, 100 + qrand() % 50); } m_data.append(dataVec); } // 每隔2秒超时 timer.start(2000); connect(&timer, SIGNAL(timeout()), this, SLOT(onGenerateData()));}TableModel::~TableModel(){ qDeleteAll(m_data);}int TableModel::rowCount(const QModelIndex &parent) const{ Q_UNUSED(parent) return m_data.count();}int TableModel::columnCount(const QModelIndex &parent) const{ Q_UNUSED(parent) return m_columnCount;}QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const{ if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) return QString("201%1").arg(section); else return QString("%1").arg(section + 1);}QVariant TableModel::data(const QModelIndex &index, int role) const{ if (role == Qt::DisplayRole) { return m_data[index.row()]->at(index.column()); } else if (role == Qt::EditRole) { return m_data[index.row()]->at(index.column()); } return QVariant();}bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role){ if (index.isValid() && role == Qt::EditRole) { m_data[index.row()]->replace(index.column(), value.toDouble()); emit dataChanged(index, index); return true; } return false;}Qt::ItemFlags TableModel::flags(const QModelIndex &index) const{ return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;}void TableModel::generateData(){ // 生成新的数据 for (int i = 0; i < m_rowCount; i++) { for (int k = 0; k < m_data.at(i)->size(); k++) { m_data.at(i)->replace(k, 100 + qrand() % 50); } } QModelIndex leftTop = index(0, 0); QModelIndex rightBottom = index(m_rowCount - 1, m_columnCount - 1); // 生成新数据后发送模型数据发生变化的信号dataChanged emit dataChanged(leftTop, rightBottom);}void TableModel::onGenerateData(){ generateData();}
增加MainWindow类:
MainWindow.h文件如下:#ifndef MAINWINDOW_H#define MAINWINDOW_H#include#include #include #include "ChartWidget/BarModelMapperChartWidget.h"#include "Model/TableModel.h"/** * @brief 程序主界面类 */class MainWindow : public QWidget{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = NULL);private: BarModelMapperChartWidget* m_barModelMapperChartWidget;//报表组件 QTableView* m_tableView;//表格视图组件 TableModel* m_model;//表格模型};#endif // MAINWINDOW_H
MainWindow.cpp文件如下:
#include "MainWindow.h"MainWindow::MainWindow(QWidget *parent) : QWidget(parent){ m_model = new TableModel(); m_barModelMapperChartWidget = new BarModelMapperChartWidget(this); m_barModelMapperChartWidget->initModelMapper(m_model); m_tableView = new QTableView(this); m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_tableView->setModel(m_model); QHBoxLayout* layout = new QHBoxLayout; layout->addWidget(m_tableView); layout->addWidget(m_barModelMapperChartWidget); setLayout(layout); resize(800, 400);}
main.cpp文件:
#include#include "MainWindow.h"int main(int argc, char* argv[]){ QApplication app(argc, argv); MainWindow w; w.show(); return app.exec();}
CMakeLists.txt文件如下:
# CMake版本约束cmake_minimum_required(VERSION 2.8.3)#工程名称project(CMakeDemo)set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_FLAGS "-fPIC")set(CMAKE_BUILD_TYPE "Debug")# 增加子目录ChartWidget的源码到变量SOURCESaux_source_directory(ChartWidget SOURCES)# 增加子目录Model的源码到变量SOURCESaux_source_directory(Model SOURCES)# 设置QT安装路径set(CMAKE_PREFIX_PATH "/usr/local/Trolltech/Qt5.10.1/5.10.1/gcc_64")set(CMAKE_INCLUDE_CURRENT_DIR ON)# 开启Qt MOCset(CMAKE_AUTOMOC ON)#开启Qt ROCset(CMAKE_AUTORCC ON)# 开启Qt UICset(CMAKE_AUTOUIC ON)set(QT Core Gui Widgets Charts)# 查找Qt库find_package(Qt5 REQUIRED ${QT})if(Qt5_FOUND) include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Charts_INCLUDE_DIRS}) set(QT_LIBRARIES ${Qt5Widgets_LIBRARIES} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Charts_LIBRARIES}) # 增加可执行文件 add_executable(${PROJECT_NAME} ${SOURCES} main.cpp MainWindow.cpp) target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES})endif(Qt5_FOUND)
QtCreator管理工程如下:
编译、调试可以使用QtCreator直接进行,方便快捷。如果需要调试,必须在CMakeLists.txt设置(CMAKE_BUILD_TYPE为Debug。set(CMAKE_BUILD_TYPE "Debug")运行结果如下:源码示例:
转载于:https://blog.51cto.com/9291927/2396966