博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GNU开发工具——CMake构建Qt工程实践
阅读量:6407 次
发布时间:2019-06-23

本文共 11010 字,大约阅读时间需要 36 分钟。

GNU开发工具——CMake构建Qt工程实践

一、CMake构建Qt工程

1、Qt工程源码

创建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();}

2、Qt4和Qt5兼容宏

编写兼容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)

3、CMakeLists.txt编写

编写工程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)

4、构建工程

Migration工程内创建build目录,进入build目录,进行构建。

cmake ..make

5、CMake的Qt相关变量

对于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目录层

二、QtCreator使用CMake构建Qt工程

1、QtCreator创建Qt工程(CMake构建)

选择新建工程,创建一个Plain C++ Application。

GNU开发工具——CMake构建Qt工程实践
选择使用CMake构建工程:
GNU开发工具——CMake构建Qt工程实践
选择使用的Qt Kits版本:
GNU开发工具——CMake构建Qt工程实践

2、增加C++类

选择菜单栏新建文件按钮,选择Files and Classes,C++ Class。

GNU开发工具——CMake构建Qt工程实践
填写创建C++类的名称BarModelMapperChartWidget:
GNU开发工具——CMake构建Qt工程实践
选择创建类文件所在位置,点击浏览按钮:
GNU开发工具——CMake构建Qt工程实践
点击新建目录按钮创建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类:

GNU开发工具——CMake构建Qt工程实践
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类:

GNU开发工具——CMake构建Qt工程实践
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();}

3、工程CMakeLists.txt文件

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)

4、构建

QtCreator管理工程如下:

GNU开发工具——CMake构建Qt工程实践
编译、调试可以使用QtCreator直接进行,方便快捷。
如果需要调试,必须在CMakeLists.txt设置(CMAKE_BUILD_TYPE为Debug。
set(CMAKE_BUILD_TYPE "Debug")
运行结果如下:
GNU开发工具——CMake构建Qt工程实践

源码示例:

转载于:https://blog.51cto.com/9291927/2396966

你可能感兴趣的文章
【数据结构】线性表(一):顺序列表
查看>>
利用Mallet工具自动挖掘文本Topic
查看>>
Windows下oracle打补丁步骤
查看>>
Python教程(一)Python简介
查看>>
asp.net forms认证
查看>>
Hadoop 公平调度器算法调度解析
查看>>
Linux Foundation(笔记)
查看>>
Java学习第二十五天
查看>>
vim配置
查看>>
ubuntu 把软件源修改为国内源和更新
查看>>
随机产生四则运算,导入导出文件
查看>>
位运算符
查看>>
winform自定义控件
查看>>
C#编码好习惯
查看>>
避其锋芒,侧翼出击。——司马亮创业回忆录(一)
查看>>
scope
查看>>
一起谈.NET技术,晚绑定场景下对象属性赋值和取值可以不需要PropertyInfo
查看>>
一起谈.NET技术,.Net Framework源代码中的模式之Prototype(原型模式)
查看>>
[shell 命令] find 查找文件
查看>>
windows下启动mysql服务的命令行启动和手动启动方法
查看>>