Я использую Qt5 в повседневной работе и однажды рассматривал CGAL в качестве возможной прикладной базы (не углубляясь в этом направлении - пока нет).Следовательно, этот вопрос вызвал у меня любопытство.
Я покопался в исходном коде CGAL на github и выяснил, почему появляется сообщение об ошибке
QCoreApplication::exec: The event loop is already running
.
Для этогоЯ скопировал соответствующие строки из CGAL на github: Многогранник / include / CGAL / draw_polyhedron.h :
template<class Polyhedron, class ColorFunctor>
void draw(const Polyhedron& apoly,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"polyhedron_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
Глядя на этот исходный код, становится очевидным, что CGAL::draw()
небольшое полнофункциональное приложение Qt, которое создает собственный экземпляр QApplication
.ОП, в свою очередь, попытался вставить CGAL::draw()
в ее / его собственное приложение Qt.Не допускается создавать экземпляры любых производных QCoreApplication
более одного раза (в соответствии с документом Qt QApplication
):
Для любого приложения с графическим интерфейсом, использующего Qt, существуетэто точно один объект QApplication, независимо от того, имеет ли приложение 0, 1, 2 или более окон в любой момент времени.
(Подчеркивая не мой.)
Документ CGAL.предоставляет (еще более короткий) пример в Polyhedron / draw_polyhedron.cpp , чтобы сделать это правильно:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/draw_polyhedron.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
int main(int argc, char* argv[])
{
Polyhedron P;
std::ifstream in1((argc>1)?argv[1]:"data/cross.off");
in1 >> P;
CGAL::draw(P);
return EXIT_SUCCESS;
}
, но нет места для вставки QFileDialog
в нужной точке.
Следовательно, CGAL::draw()
- это неправильный инструмент для того, что OP (вероятно) намеревается сделать - внедрить рендеринг многогранника CGAL в приложение Qt.Для этого необходимо напрямую использовать вещи, которые называются где-то внутри CGAL::draw()
.
Итак, вот что мне кажется подходящим:создание SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
(основного или дочернего) виджета в OP-приложении Qt.
Затем я немного прошелся по репозиторию github, чтобы выяснить, из какого виджета Qt на самом деле CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
происходит, и нашел следующее наследование.:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
Итак, CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
можно использовать как любой QWidget
(что подразумевает превращение его в главное окно).Он также может стать центральным виджетом QMainWindow
, который получает строку меню / панель инструментов с QAction
, чтобы открыть QFileDialog
, запросить путь к файлу, открыть поток файлов с этим путем к файлу и загрузитьсетка из этого файлового потока.
Есть еще одна небольшая деталь, на которую я наткнулся: CGAL::Polyhedron
должен быть передан CGAL::SimplePolyhedronViewerQt
в конструкторе и по константной ссылке.Чтобы учесть это, ИМХО необходимо (после успешной загрузки сетки) создать экземпляр CGAL::SimplePolyhedronViewerQt
с помощью new
и впоследствии установить / добавить его в родительский виджет.Если это неприемлемо, вероятно, нужно пойти еще глубже и заменить CGAL::SimplePolyhedronViewerQt
собственной реализацией, используя исходный код первого в качестве «шпаргалки».
Вот как такое приложение могло бывыглядит так:
#include <fstream>
#include <QtWidgets>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/draw_polyhedron.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
CGAL::DefaultColorFunctorPolyhedron fColor;
Polyhedron mesh;
// setup UI
QMainWindow qWin;
QToolBar qToolbar;
QAction qCmdLoad(QString::fromUtf8("Load File..."));
qToolbar.addAction(&qCmdLoad);
qWin.addToolBar(&qToolbar);
qWin.show();
// install signal handlers
QObject::connect(&qCmdLoad, &QAction::triggered,
[&qWin, &mesh, &fColor]() {
const QString filePath = QFileDialog::getOpenFileName(
&qWin,
QString::fromUtf8("Open .off model"),
QString::fromUtf8("/home"),
QString::fromUtf8("*.off"));
if (filePath.isEmpty()) return;
std::ifstream fIn(filePath.toUtf8().data());
if (!(fIn >> mesh) || mesh.is_empty()) {
qDebug() << "Loading of" << filePath << "failed!";
return;
}
qWin.setCentralWidget(
new CGAL::SimplePolyhedronViewerQt<Polyhedron, CGAL::DefaultColorFunctorPolyhedron>(
&qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
qWin.centralWidget()->show();
});
// runtime loop
return app.exec();
}
Пожалуйста, возьмите это с «зерном соли» - у меня нет CGAL под рукой, и я не смог скомпилировать / протестировать приведенный выше код.