我如何在 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 上。

要使用库,您需要设置两件事:追加 INCLUDEPATHLIBS,您可以在 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

完整来源:https://github.com/mugiseyebrows/app-and-library.git