由于您似乎是 CMake 新手,我将围绕 mohamadp91 提供的答案添加一些代码。
您的问题是当您运行cmake .. 时,当您运行make 并执行您的软件时,Application.glade 文件永远不会复制到build 目录中。此时,应用程序尝试加载 build/example/Application.glade 文件,但没有找到任何文件,您会收到错误消息。
在使用普通 Makefile 时不会发生这种情况,因为您不是在 build 中构建目录,而是直接在 example 目录旁边。然后应用程序可以找到 Glade 文件。
我做了一个小例子来重现你的问题。它具有相同的目录结构:
├── build
├── CMakeLists.txt
├── example
│ ├── CMakeLists.txt
│ └── Application.glade
└── main.cpp
它只有一个main.cpp 文件,它试图在example 下加载一个资源(在这种情况下是Glade 文件,就像你一样)。这是 C++ 代码:
#include <iostream>
#include <gtkmm.h>
constexpr int FILE_ERROR = 1;
constexpr int MARKUP_ERROR = 2;
constexpr int BUILDER_ERROR = 3;
Gtk::ApplicationWindow* window = nullptr;
int main(int argc, char **argv)
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
auto builder = Gtk::Builder::create();
try
{
// Try to use Application.glade:
builder->add_from_file("example/Application.glade");
}
catch(const Glib::FileError& ex)
{
// This was your case, because the Application.glade file could
// not be located:
std::cout << "File error :" << ex.what() << std::endl;
return FILE_ERROR;
}
catch(const Glib::MarkupError& ex)
{
std::cout << "Markup error :" << ex.what() << std::endl;
return MARKUP_ERROR;
}
catch(const Gtk::BuilderError& ex)
{
std::cout << "Builder error :" << ex.what() << std::endl;
return BUILDER_ERROR;
}
//Get the GtkBuilder-instantiated Dialog:
builder->get_widget("MainWindow", window);
if(window)
{
app->run(*window);
}
delete window;
return 0;
}
该示例显示了如何捕获Glib::FileError 异常并避免段错误。 Glade 文件很简单,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkApplicationWindow" id="MainWindow">
<property name="can_focus">False</property>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkButton" id="MainButton">
<property name="label" translatable="yes">Hello World</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
</child>
</object>
</interface>
在顶级目录中,我使用add_subdirectory 命令告诉CMake 进入example 子目录并处理位于那里的CMakeLists.txt 文件:
cmake_minimum_required(VERSION 3.1.0)
project(Example_App)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(PkgConfig)
pkg_check_modules(GTKMM gtkmm-3.0)
include_directories(${GTKMM_INCLUDE_DIRS})
link_directories(${GTKMM_LIBRARY_DIRS})
set(SOURCE_FILES main.cpp)
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES} main.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} ${GTKMM_LIBRARIES})
# CMake is gonna read the 'CMakeLists.txt' file located under 'example':
add_subdirectory(example)
在该文件中,我只是将Application.glade 文件复制到构建目录中example 下:
file(COPY Application.glade DESTINATION ${CMAKE_CURRENT_BINARY_DIR})