C++ 将somedialog.h包含到项目的其他部分中,会使ui_somedialog.h对编译器不可见
我试图在项目中以不同的方式使用自定义Qt对话框。有两种情况下会出现相同的问题 1。我将对话框作为库包含到主项目中。 该库是一个更大的SubDRS项目的一部分,该项目还包含将使用它的主应用程序。以下是项目树: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
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中查看代码