在qt窗口小部件应用程序的CGAl包中运行draw_polygon示例



我尝试在Qt小部件应用程序中使用CGAL示例:示例

main.ccp:

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
     MainWindow w;
 w.show();
        return a.exec();
}

主窗口.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);
}

当我运行它时,它打开对话框文件选择.off文件,然后显示以下错误:

QCoreApplication::exec: The event loop is already running

有什么需要帮忙的吗?

我在日常业务中使用Qt5,并曾将CGAL视为可能的应用程序基础(现在还没有深入研究(。因此,这个问题使我感到好奇。

我在github上挖掘了CGAL的源代码,发现了错误消息的原因

QCoreApplication::exec: The event loop is already running

发生。

为此,我在github上复制了CGAL的相关行: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",""};
    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()嵌入到她/他自己的Qt应用程序中。不允许多次引用QCoreApplication的任何衍生物(根据QApplication的Qt文档(:

对于任何使用Qt的GUI应用程序,无论应用程序在任何给定时间是否具有0、1、2或更多窗口,都会有一个QApplication对象。

(强调而不是矿。(

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;
}

但是在正确的点处没有插入CCD_ 6的位置。

因此,对于OP(可能(打算做的事情,CGAL::draw()是错误的工具–将CGAL多面体渲染嵌入到Qt应用程序中。为此,有必要直接使用CGAL::draw()内部某个地方调用的东西。

因此,这对我来说似乎是合适的:
使SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>成为OP Qt应用程序中的(主或子(小部件。

然后,我浏览了github repo,找出了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必须在构造函数中通过const引用提供给CGAL::SimplePolyhedronViewerQt。为此,IMHO有必要(在成功加载网格之后(通过new构建CGAL::SimplePolyhedronViewerQt实例,然后将其设置/添加到父窗口小部件中。如果这是不可接受的,那么可能需要更深入地使用自己的实现来替换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,无法编译/测试上面的代码。

CGAL::draw((已经处理了Qt的内容。您正试图打开另一个主窗口中的主窗口。只需在main((函数中调用CGAL::draw(mesh(,就可以了。

编辑:这正是Sheff以更详细的方式解释的。

最新更新