C++ 将somedialog.h包含到项目的其他部分中,会使ui_somedialog.h对编译器不可见

C++ 将somedialog.h包含到项目的其他部分中,会使ui_somedialog.h对编译器不可见,c++,qt,dialog,shared-libraries,qmake,C++,Qt,Dialog,Shared Libraries,Qmake,我试图在项目中以不同的方式使用自定义Qt对话框。有两种情况下会出现相同的问题 1。我将对话框作为库包含到主项目中。 该库是一个更大的SubDRS项目的一部分,该项目还包含将使用它的主应用程序。以下是项目树: AppProject |_AppProject.pro |_MyApp |_myapp.pro |_main.cpp |_mainwindow.h |_mainwindow.cpp |_mainwindow.ui |_GUILib |_guilib.pro |_g

我试图在项目中以不同的方式使用自定义Qt对话框。有两种情况下会出现相同的问题

1。我将对话框作为库包含到主项目中。 该库是一个更大的SubDRS项目的一部分,该项目还包含将使用它的主应用程序。以下是项目树:

AppProject
|_AppProject.pro
|_MyApp
  |_myapp.pro
  |_main.cpp
  |_mainwindow.h
  |_mainwindow.cpp
  |_mainwindow.ui
|_GUILib
  |_guilib.pro
  |_guilib_decl.h
  |_somedialog.h
  |_somedialog.cpp
  |_somedialog.ui
此处的源文件:



AppProject是一个普通的细分项目,包括MyApp和GUILib:

TEMPLATE = subdirs

SUBDIRS += MyApp \
           GUILib

MyApp.depends = GUILib
MyApp是一个普通的应用程序模板:

QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MyApp
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

CONFIG += c++14

DEPENDPATH += ../GUILib

INCLUDEPATH += ../GUILib

LIBS += -L../GUILib -lGUILib  

HEADERS += mainwindow.h \

SOURCES += main.cpp \
           mainwindow.cpp \

FORMS +=   mainwindow.ui \
以下是lib项目文件:

QT += core widgets gui

TARGET = GUILib
TEMPLATE = lib

CONFIG += c++14
CONFIG -= debug_and_release

DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += GUILIB_LIBRARY


HEADERS += \
    guilib_decl.h \
    somedialog.h

SOURCES += \
    guilib.cpp \
    somedialog.cpp

FORMS += \
    somedialog.ui
该库可以自行构建(没有问题,ui_somedialog.h已找到),但如果我将somedialog.h包含到mainwindow.h中,则编译器会发出以下错误消息:

ui\u somedialog.h:没有这样的文件或目录

2。我将对话框作为非库包含到测试中。

此处,项目树如下所示:

AppProject
    |_AppProject.pro
    |_MyApp
      |_myapp.pro
      |_main.cpp
      |_mainwindow.h
      |_mainwindow.cpp
      |_mainwindow.ui
      |_somedialog.h
      |_somedialog.cpp
      |_somedialog.ui
    |_Tests
      |_tests.pro
      |_main.cpp
      |_tst_somedialog.cpp
QT += testlib
QT += widgets gui

TARGET = Tests
TEMPLATE = app

CONFIG += c++14
CONFIG += testcase 
CONFIG -= debug_and_release

INCLUDEPATH += ../MyApp

SOURCES += main.cpp \
    tst_somedialog.cpp \
它仍然是一个subdirs项目,但这次其中一个是测试项目,对话框只是应用程序的一个普通部分(非lib)

测试的项目文件如下所示:

AppProject
    |_AppProject.pro
    |_MyApp
      |_myapp.pro
      |_main.cpp
      |_mainwindow.h
      |_mainwindow.cpp
      |_mainwindow.ui
      |_somedialog.h
      |_somedialog.cpp
      |_somedialog.ui
    |_Tests
      |_tests.pro
      |_main.cpp
      |_tst_somedialog.cpp
QT += testlib
QT += widgets gui

TARGET = Tests
TEMPLATE = app

CONFIG += c++14
CONFIG += testcase 
CONFIG -= debug_and_release

INCLUDEPATH += ../MyApp

SOURCES += main.cpp \
    tst_somedialog.cpp \
不幸的是,对话框是否是lib似乎并不重要,编译器在这两种情况下都会显示相同的错误消息。最有趣的是,ui文件在它应该在的地方(uic完成了它的工作),因此理论上编译器应该在这两种情况下都能找到它,但由于某种原因它没有找到。有什么秘密是我不知道的吗?为什么当我尝试在其他地方使用ui_somedialog.h时,它对编译器不可见

谢谢

编辑:修改为包括场景2


EDIT2:为场景1添加了源文件。

最好的选择是将所有gui保留在主应用程序中,但由于这并不总是一个选项,请进一步阅读

首先,我想提到发生这种情况的原因,因为
GUILib/GeneratedFiles
(或者配置Qt工具以放置
uic
生成的文件的路径)不在MyApp的
INCLUDEPATH
中,快速破解方法是将该路径添加到
INCLUDEPATH
,但这会使事情进一步复杂化,比如如果要部署库,需要确保将工具配置为在所有平台上以相同路径创建文件,因此不推荐使用此解决方案

一个更好的解决方案是创建一个类,该类使用封装对话框,并且基本上来自所有外部源,您只包括包含PIMPL“接口”的头

注意:使用
QObject
时,父对象负责删除其子对象,因此为了避免重复删除,在对话框中设置父对象时,不要使用
std::unique_ptr

乐: 或者是一个3RD选项(实际上这只是piml,所以在技术上它仍然是第二个选项)是为了避免将生成的文件(uijAddiaby.h)包含到某个对话框中。h(包括使用库的地方的头),请参阅有关如何将UIC生成代码使用到C++代码的文档。(使用指针成员变量查看

//一些对话

这是一种类似PIMPL的方法,您只需转发引用内部类并向其导出接口


有一种方法可以设置您希望Qt工具为您生成代码的方法,但我现在找不到,对我来说,当前的工具似乎总是使用这种成员指针方法。

最好的选择是将所有gui保留在主应用程序中,但由于这并不总是一个选项,请进一步阅读

首先,我想说明发生这种情况的原因,因为
GUILib/GeneratedFiles
(或者配置Qt工具放置
uic
生成的文件的路径)不在MyApp的
INCLUDEPATH
中,快速破解方法是将该路径添加到
INCLUDEPATH
,但这将使事情更加复杂,例如如果要部署库,需要确保将工具配置为在所有平台上以相同路径创建文件,因此不推荐使用此解决方案

一个更好的解决方案是创建一个类,该类使用封装对话框,并且基本上来自所有外部源,您只包括包含PIMPL“接口”的头

注意:使用
QObject
时,父对象负责删除其子对象,因此为了避免重复删除,在对话框中设置父对象时,不要使用
std::unique_ptr

乐: 或者是一个3RD选项(实际上这只是piml,所以在技术上它仍然是第二个选项)是为了避免将生成的文件(uijAddiaby.h)包含到某个对话框中。h(包括使用库的地方的头),请参阅有关如何将UIC生成代码使用到C++代码的文档。(使用指针成员变量查看

//一些对话

这是一种类似PIMPL的方法,您只需转发引用内部类并向其导出接口


有一种方法可以设置您希望Qt工具为您生成代码的方法,但我现在找不到,对我来说,当前的工具似乎总是使用这种成员指针方法。

带有对话框的库?这是一种好方法吗?这只是一个概念。老实说,在我尝试在中使用对话框时,也出现了同样的问题一个单元测试。如果在测试中没有使用ui_somedialog.h,则会找到它,但另一方面,如果它包含在测试中,则会出现相同的问题。我认为如果我将要测试的对话框设置为库(以及所有其他gui元素),问题可以解决,但显然不是。这些问题似乎有某种关联。我认为如果我找到了解决方案,测试问题也可以用同样的方法解决。我们需要在somedialog.cpp中查看代码