我如何在 Qt 中使用子项目?
How can I use sub-projects in Qt?
我正在尝试转向 Qt 以重写一个包含大量静态库的 win32 项目,因此作为初步测试项目,我尝试按照 https://www.toptal.com/qt/vital-guide-qmake 中的说明创建一个子目录项目。我在这个网站上看到了很多其他的例子和类似的问题,但其中 none 只是一个简单的例子,在我构建它时实际有效,所以我展示这个最小的例子,希望有人能告诉我我错过了什么。
这是文件结构;
project/
project.pro
app/
app.pro
main.ccp
library/
library.pro
mainwindow.h
library.pri
应用程序和库项目都是简单的 Qt Widgets 应用程序,使用新建子项目向导创建。该应用项目有 main.cpp;
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
库项目只有头文件 mainwindow.h 定义主窗口 class;
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {}
~MainWindow() {}
};
#endif // MAINWINDOW_H
这里是亲。文件;
project.pro;
TEMPLATE = subdirs
TARGET = project
SUBDIRS = app library
app.depends = library
app.pro;
TEMPLATE = app
TARGET = app
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
include(../library/library.pri)
library.pro;
TEMPLATE = lib
TARGET = library
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
HEADERS += \
mainwindow.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
library.pri
最后,library.pri 文件;
LIBTARGET = library
BASEDIR = $${PWD}
INCLUDEPATH *= $${BASEDIR}/include
LIBS += -L$${DESTDIR} -llibrary
这样做的目的是检查我是否可以在 Qt 中编写一个项目,其中一个项目中的函数可以引用另一个项目中的 class。当编译为单个项目时,在同一个项目中使用 main.cpp 和 mainwindow.h,您会在屏幕上得到通常的应用程序 window,没有任何错误,所以我知道 main.cpp 和MainWindow class 很好;按原样编译,有两个子项目,我在第 1 行 main.cpp 得到“'mainwindow.h' 文件未找到”,第 6 行得到“未知类型名称 'MainWindow'”,main.cpp,所以库项目显然没有被应用程序项目正确引用。我是 Qt 的新手,完全没有使用 qmake 的经验,我们将不胜感激,而且据我所知,我不是唯一为此苦苦挣扎的人,如果有人可以帮助完成这项工作,我会把它放在 gtihub 上。
要使用库,您需要设置两件事:追加 INCLUDEPATH
和 LIBS
,您可以在 pri 文件中完成,然后包含在 app
中,如果出现错误提示“文件 *.h 未找到”表示 INCLUDEPATH
不完整。
你可以这样做:
项目结构
project/
├── app
│ ├── app.pro
│ └── main.cpp
├── library
│ ├── library.pri
│ ├── library.pro
│ ├── mainwindow.cpp
│ ├── mainwindow.h
│ └── mainwindow.ui
└── project.pro
project.pro
TEMPLATE = subdirs
SUBDIRS += \
app \
library
app.depends = library
library.pri
INCLUDEPATH += $$PWD
win32 {
CONFIG(debug, debug|release) {
LIBS += -L$$PWD/debug
} else {
LIBS += -L$$PWD/release
}
} else {
LIBS += -L$$PWD
}
LIBS += -llibrary
library.pro
QT += gui widgets
TEMPLATE = lib
CONFIG += staticlib
SOURCES += \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
app.pro
QT += gui widgets
SOURCES += main.cpp
include($$PWD/../library/library.pri)
QtCreator 默认使用影子构建(它可以在项目页面上禁用),所以如果你从 QtCreator IDE 而不是 shell(命令行)构建,你可能使用影子构建.在这种情况下,包括静态库在内的所有构建工件都是在源目录之外的一个名为 build-${project-name}-${device-type}-${build-config}
的单独目录中构建的(在我们的例子中是 build-project-Desktop-Debug),因此 -L$$PWD
不会工作,有 OUT_PWD
为此,不幸的是,由于某种原因,它指向的不是 pri 目录,而是 pro 目录(build-project-Desktop-Debug/app 在这种情况下),事情变得有点毛茸茸。这是适用于影子和普通构建的 library.pri
:
INCLUDEPATH += $$PWD
win32 {
CONFIG(debug, debug|release) {
LIBS += -L$$PWD/debug -L$$OUT_PWD/../library/debug
} else {
LIBS += -L$$PWD/release -L$$OUT_PWD/../library/release
}
} else {
LIBS += -L$$PWD -L$$OUT_PWD/../library
}
LIBS += -llibrary
我正在尝试转向 Qt 以重写一个包含大量静态库的 win32 项目,因此作为初步测试项目,我尝试按照 https://www.toptal.com/qt/vital-guide-qmake 中的说明创建一个子目录项目。我在这个网站上看到了很多其他的例子和类似的问题,但其中 none 只是一个简单的例子,在我构建它时实际有效,所以我展示这个最小的例子,希望有人能告诉我我错过了什么。
这是文件结构;
project/
project.pro
app/
app.pro
main.ccp
library/
library.pro
mainwindow.h
library.pri
应用程序和库项目都是简单的 Qt Widgets 应用程序,使用新建子项目向导创建。该应用项目有 main.cpp;
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
库项目只有头文件 mainwindow.h 定义主窗口 class;
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {}
~MainWindow() {}
};
#endif // MAINWINDOW_H
这里是亲。文件;
project.pro;
TEMPLATE = subdirs
TARGET = project
SUBDIRS = app library
app.depends = library
app.pro;
TEMPLATE = app
TARGET = app
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
include(../library/library.pri)
library.pro;
TEMPLATE = lib
TARGET = library
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
HEADERS += \
mainwindow.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
library.pri
最后,library.pri 文件;
LIBTARGET = library
BASEDIR = $${PWD}
INCLUDEPATH *= $${BASEDIR}/include
LIBS += -L$${DESTDIR} -llibrary
这样做的目的是检查我是否可以在 Qt 中编写一个项目,其中一个项目中的函数可以引用另一个项目中的 class。当编译为单个项目时,在同一个项目中使用 main.cpp 和 mainwindow.h,您会在屏幕上得到通常的应用程序 window,没有任何错误,所以我知道 main.cpp 和MainWindow class 很好;按原样编译,有两个子项目,我在第 1 行 main.cpp 得到“'mainwindow.h' 文件未找到”,第 6 行得到“未知类型名称 'MainWindow'”,main.cpp,所以库项目显然没有被应用程序项目正确引用。我是 Qt 的新手,完全没有使用 qmake 的经验,我们将不胜感激,而且据我所知,我不是唯一为此苦苦挣扎的人,如果有人可以帮助完成这项工作,我会把它放在 gtihub 上。
要使用库,您需要设置两件事:追加 INCLUDEPATH
和 LIBS
,您可以在 pri 文件中完成,然后包含在 app
中,如果出现错误提示“文件 *.h 未找到”表示 INCLUDEPATH
不完整。
你可以这样做:
项目结构
project/
├── app
│ ├── app.pro
│ └── main.cpp
├── library
│ ├── library.pri
│ ├── library.pro
│ ├── mainwindow.cpp
│ ├── mainwindow.h
│ └── mainwindow.ui
└── project.pro
project.pro
TEMPLATE = subdirs
SUBDIRS += \
app \
library
app.depends = library
library.pri
INCLUDEPATH += $$PWD
win32 {
CONFIG(debug, debug|release) {
LIBS += -L$$PWD/debug
} else {
LIBS += -L$$PWD/release
}
} else {
LIBS += -L$$PWD
}
LIBS += -llibrary
library.pro
QT += gui widgets
TEMPLATE = lib
CONFIG += staticlib
SOURCES += \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
app.pro
QT += gui widgets
SOURCES += main.cpp
include($$PWD/../library/library.pri)
QtCreator 默认使用影子构建(它可以在项目页面上禁用),所以如果你从 QtCreator IDE 而不是 shell(命令行)构建,你可能使用影子构建.在这种情况下,包括静态库在内的所有构建工件都是在源目录之外的一个名为 build-${project-name}-${device-type}-${build-config}
的单独目录中构建的(在我们的例子中是 build-project-Desktop-Debug),因此 -L$$PWD
不会工作,有 OUT_PWD
为此,不幸的是,由于某种原因,它指向的不是 pri 目录,而是 pro 目录(build-project-Desktop-Debug/app 在这种情况下),事情变得有点毛茸茸。这是适用于影子和普通构建的 library.pri
:
INCLUDEPATH += $$PWD
win32 {
CONFIG(debug, debug|release) {
LIBS += -L$$PWD/debug -L$$OUT_PWD/../library/debug
} else {
LIBS += -L$$PWD/release -L$$OUT_PWD/../library/release
}
} else {
LIBS += -L$$PWD -L$$OUT_PWD/../library
}
LIBS += -llibrary