运行 draw_polygon qt widget 应用程序中 CGAl 包中的示例
running draw_polygon example in CGAl package in qt widget application
我尝试在 Qt 小部件应用程序中遵循 CGAL 示例:
example
main.ccp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.ccp :
#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;
void MainWindow::on_pushButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,tr("Open .off model"), "/home", tr("*.off"));
draw_poly(fileName);
}
void MainWindow::draw_poly(QString fileName)
{
QByteArray inBytes;
const char *c;
inBytes = fileName.toUtf8();
c = inBytes.constData();
std::ifstream input(c);
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << "Not a valid off file." << std::endl;
// return 1;
}
input >> mesh;
CGAL::draw(mesh);
}
当我 运行 它时,它打开对话框文件到 select .off 文件,然后它显示以下错误:
QCoreApplication::exec: The event loop is already running
有什么帮助吗?
我在日常业务中使用 Qt5,并且曾经考虑将 CGAL 作为可能的应用程序基础(没有进一步朝这个方向发展——还没有)。因此,这个问题让我很好奇。
我在 github 上仔细研究了 CGAL 的源代码,发现了错误消息
的原因
QCoreApplication::exec: The event loop is already running
发生。
为此,我从 CGAL on github: Polyhedron/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","[=11=]"};
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
实例。 OP 又试图将 CGAL::draw()
嵌入 her/his 自己的 Qt 应用程序中。不允许多次实例化 QCoreApplication
的任何衍生物(根据 QApplication
的 Qt 文档):
For any GUI application using Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any given time.
(强调不是我的。)
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()
.
内部某处调用的东西
所以,这对我来说似乎是合适的:
在 OPs Qt 应用程序中制作 SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
一个(主或子)小部件。
然后我浏览了 github 存储库,以找出 CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
实际上是从哪个 Qt 小部件派生的,并发现了以下继承:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
因此,CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
可以像任何 QWidget
一样使用(包括使其成为主要的 window)。它也可以成为 QMainWindow
的中心小部件,它获得一个带有 QAction
的菜单 bar/tool 栏以打开 QFileDialog
、请求文件路径、打开文件流使用此文件路径,并从此文件流加载网格。
还有一个我偶然发现的小细节:CGAL::Polyhedron
必须在构造函数中通过 const 引用提供给 CGAL::SimplePolyhedronViewerQt
。考虑到这一点,恕我直言,有必要(在成功加载网格后)通过 new
构造 CGAL::SimplePolyhedronViewerQt
实例,然后 set/add 将其构造为父小部件。如果这是不可接受的,可能有必要更深入地用自己的实现替换 CGAL::SimplePolyhedronViewerQt
,使用前者的源代码作为“cheat-sheet”。
这样的应用程序可能是这样的:
#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,无法 compile/test 上面的代码。
CGAL::draw() 已经处理了 Qt 的东西。您正试图在另一个主窗口中打开一个主窗口。只需在您的 main() 函数中调用 CGAL::draw(mesh) 即可,它会起作用。
编辑:这正是 Sheff 以更详细的方式解释的内容。
我尝试在 Qt 小部件应用程序中遵循 CGAL 示例: example
main.ccp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.ccp :
#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;
void MainWindow::on_pushButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,tr("Open .off model"), "/home", tr("*.off"));
draw_poly(fileName);
}
void MainWindow::draw_poly(QString fileName)
{
QByteArray inBytes;
const char *c;
inBytes = fileName.toUtf8();
c = inBytes.constData();
std::ifstream input(c);
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << "Not a valid off file." << std::endl;
// return 1;
}
input >> mesh;
CGAL::draw(mesh);
}
当我 运行 它时,它打开对话框文件到 select .off 文件,然后它显示以下错误:
QCoreApplication::exec: The event loop is already running
有什么帮助吗?
我在日常业务中使用 Qt5,并且曾经考虑将 CGAL 作为可能的应用程序基础(没有进一步朝这个方向发展——还没有)。因此,这个问题让我很好奇。
我在 github 上仔细研究了 CGAL 的源代码,发现了错误消息
的原因QCoreApplication::exec: The event loop is already running
发生。
为此,我从 CGAL on github: Polyhedron/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","[=11=]"};
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
实例。 OP 又试图将 CGAL::draw()
嵌入 her/his 自己的 Qt 应用程序中。不允许多次实例化 QCoreApplication
的任何衍生物(根据 QApplication
的 Qt 文档):
For any GUI application using Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any given time.
(强调不是我的。)
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()
.
所以,这对我来说似乎是合适的:
在 OPs Qt 应用程序中制作 SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
一个(主或子)小部件。
然后我浏览了 github 存储库,以找出 CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
实际上是从哪个 Qt 小部件派生的,并发现了以下继承:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
因此,CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
可以像任何 QWidget
一样使用(包括使其成为主要的 window)。它也可以成为 QMainWindow
的中心小部件,它获得一个带有 QAction
的菜单 bar/tool 栏以打开 QFileDialog
、请求文件路径、打开文件流使用此文件路径,并从此文件流加载网格。
还有一个我偶然发现的小细节:CGAL::Polyhedron
必须在构造函数中通过 const 引用提供给 CGAL::SimplePolyhedronViewerQt
。考虑到这一点,恕我直言,有必要(在成功加载网格后)通过 new
构造 CGAL::SimplePolyhedronViewerQt
实例,然后 set/add 将其构造为父小部件。如果这是不可接受的,可能有必要更深入地用自己的实现替换 CGAL::SimplePolyhedronViewerQt
,使用前者的源代码作为“cheat-sheet”。
这样的应用程序可能是这样的:
#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,无法 compile/test 上面的代码。
CGAL::draw() 已经处理了 Qt 的东西。您正试图在另一个主窗口中打开一个主窗口。只需在您的 main() 函数中调用 CGAL::draw(mesh) 即可,它会起作用。
编辑:这正是 Sheff 以更详细的方式解释的内容。