\
在项目中使用qt,需要将涉及Qt头文件和库包含进来,如果工程中使用了Q_OBJECT宏或*.ui文件,还需要使用moc或uic编译器先编译这些文件,才能在项目中参与编译。qt库的引入可以使用vcpkg来实现。Window系统下开发Qt(1)-- 第一个Qt程序
若项目是由CMake来构建的,如何在cmake中使用vcpkg,可以参考博客:CMake中使用vcpkg
本文在上面的博客的基础上,讨论如何用cmake自动编译Q_OBJECT宏或*.ui文件。
目录结构:
|
|--main.cpp
|--MyWindow.h
|--MyWindow.cpp
|--MyWindow.ui
|--CMakeLists.txt
其中*.ui文件是用QtDesigner生成的,用来描述界面的。可以很方便的处理复杂界面的布局。
ui文件不能直接参与编译的,需要通过qt提供的uic编译器,生成对应的C++头文件,然后在项目工程中包含此头文件才能参与编译。如何手动使用uic生成c++文件,请参考博客:Window系统下开发Qt(4)-- 生成 ui 对应的 .h和 .cpp 文件
另外,因为用到了信号和槽,需要引入Q_OBJECT宏,使用了这个宏,需要使用Qt提供的moc编译器,生成对应的C++文件,才能编译成功。如何手动使用moc生成c++文件,请参考博客:Window系统下开发Qt(2)-- 使用moc编译信号与槽
然而,上面的都需要手动调用moc或uic,若用cmake构建项目,则不适用。下面的方式,可以在cmakelists中自动调用moc或uic,生成C++文件,然后参与编译。
先上代码:
main.cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainwindow>
#include "MyWindow.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MyWindow mainwindow;
mainwindow.show();
return app.exec();
}
MyWindow.h
#include <QtWidgets/QMainwindow>
#include "ui_mywindow.h"
class MyWindow : public QMainWindow
{
Q_OBJECT
public:
MyWindow();
~MyWindow();
public slots:
void on_btnShowMsg_clicked1();
private:
Ui::MyWindowUI* m_ui;
};
MyWindow.cpp
#include <QtWidgets/QMainwindow>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QMessageBox>
#include "MyWindow.h"
MyWindow::MyWindow()
{
m_ui = new Ui::MyWindowUI();
m_ui->setupUi(this);
}
MyWindow::~MyWindow()
{
}
void MyWindow::on_btnShowMsg_clicked1()
{
QMessageBox::information(this, "MyWindow", "on_btnShowMsg_Clicked", QMessageBox::Ok);
}
MyWindow.ui(QtDesigner生成)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MyWindowUI</class>
<widget class="QWidget" name="MyWindowUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MyWindow</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>18</number>
</property>
<property name="topMargin">
<number>18</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>115</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnShowMsg">
<property name="text">
<string>ShowMessage</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>298</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>115</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
SET(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}\vcpkg\scripts\buildsystems\vcpkg.cmake")
set(EXECUTABLE_NAME QtMocDemo)
project(${EXECUTABLE_NAME})
# 将当前目录加到工程中,后面的AUTOMOC和AUTOUIC生成的中间文件,放在编译目录,因此要打开此选项
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(qt5widgets QUIET CONFIG REQUIRED)
add_executable(${EXECUTABLE_NAME} main.cpp MyWindow.h MyWindow.cpp MyWindow.ui)
# 打开AUTOMOC
set_target_properties(${EXECUTABLE_NAME} PROPERTIES AUTOMOC ON)
# 打开AUTOUIC
set_target_properties(${EXECUTABLE_NAME} PROPERTIES AUTOUIC ON)
target_link_libraries(${EXECUTABLE_NAME} ${Qt5Widgets_LIBRARIES})
在命令行执行
mkdir build
cd build
cmake -G"Visual Studio 15 2017" .. -DVCPKG_ROOT="E:\code"
msbuild qtmocdemo.sln /p:platform="Win32"
可以正常编译。
并且在编译目录可以查看中间文件
\