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

栏目: 编程工具 · 发布时间: 5年前

内容简介:创建Migration目录,在目录下创建main.cpp文件:编写兼容Qt4和Qt5的CMake宏,QtMigration.cmake文件如下:编写工程CMakeLists.txt文件,内容如下:

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

一、CMake构建Qt工程

1、Qt工程源码

创建Migration目录,在目录下创建main.cpp文件:

#include <QApplication>
#include <QLabel>

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_MODULES
macro(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 <QWidget>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QVXYModelMapper>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QVBarModelMapper>
#include <QtWidgets/QHeaderView>
#include <QtCharts/QBarCategoryAxis>
#include <QHBoxLayout>

QT_CHARTS_USE_NAMESPACE

/**
 * @brief 柱状图ModelMapper报表界面类
 */
class BarModelMapperChartWidget : public QWidget
{
    Q_OBJECT
public:
    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 <QAbstractTableModel>
#include <QHash>
#include <QRect>
#include <QVector>
#include <QTime>
#include <QColor>
#include <QTimer>
/**
 * @brief 数据模型
 */
class TableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    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<QVector<qreal> * > 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<qreal>* dataVec = new QVector<qreal>(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 <QWidget>
#include <QHBoxLayout>
#include <QTableView>
#include "ChartWidget/BarModelMapperChartWidget.h"
#include "Model/TableModel.h"

/**
 * @brief 程序主界面类
 */
class MainWindow : public QWidget
{
    Q_OBJECT
public:
    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 <QApplication>
#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的源码到变量SOURCES
aux_source_directory(ChartWidget SOURCES)
# 增加子目录Model的源码到变量SOURCES
aux_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 MOC
set(CMAKE_AUTOMOC ON)
#开启Qt ROC
set(CMAKE_AUTORCC ON)
# 开启Qt UIC
set(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://down.51cto.com/data/2461580


以上所述就是小编给大家介绍的《GNU开发工具——CMake构建Qt工程实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Linux Command Line

The Linux Command Line

William E. Shotts Jr. / No Starch Press, Incorporated / 2012-1-17 / USD 39.95

You've experienced the shiny, point-and-click surface of your Linux computer-now dive below and explore its depths with the power of the command line. The Linux Command Line takes you from your very ......一起来看看 《The Linux Command Line》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器