running draw_polygon example in CGAl package in qt widget application
I try to following CGAL example in Qt widget application :
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);
}
when I ran it , it open dialog file to select .off file ,then it shows the following error:
QCoreApplication::exec: The event loop is already running
any help ,please ?
c++ qt qt-creator fedora cgal
add a comment |
I try to following CGAL example in Qt widget application :
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);
}
when I ran it , it open dialog file to select .off file ,then it shows the following error:
QCoreApplication::exec: The event loop is already running
any help ,please ?
c++ qt qt-creator fedora cgal
add a comment |
I try to following CGAL example in Qt widget application :
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);
}
when I ran it , it open dialog file to select .off file ,then it shows the following error:
QCoreApplication::exec: The event loop is already running
any help ,please ?
c++ qt qt-creator fedora cgal
I try to following CGAL example in Qt widget application :
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);
}
when I ran it , it open dialog file to select .off file ,then it shows the following error:
QCoreApplication::exec: The event loop is already running
any help ,please ?
c++ qt qt-creator fedora cgal
c++ qt qt-creator fedora cgal
asked Nov 14 '18 at 10:48
n.mn.m
618
618
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I'm using Qt5 in daily business, and once considered CGAL as possible application base (without going further into this direction – not yet). Hence, this question made me curious.
I digged through the source code of CGAL on github and found out why the error message
QCoreApplication::exec: The event loop is already running
occurs.
For this, I copied the relevant lines from 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",""};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
Looking at this source code, it becomes obvious that CGAL::draw() is a small ful-featured Qt application in itself which establishs its own QApplication instance. The OP in turn tried to embed the CGAL::draw() in her/his own Qt application. It is not allowed to instance any derivates of QCoreApplication more than once (according to Qt doc. of QApplication):
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.
(Emphasizing not mine.)
The CGAL doc. provides an (even shorter) example in Polyhedron/draw_polyhedron.cpp to do this right:
#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;
}
but there is no place to insert the QFileDialog at the right point.
Hence, CGAL::draw() is the wrong tool for what OP (probably) intends to do – embed CGAL polyhedron rendering into a Qt application. For this, it is necessary to use the things directly which are called somewhere inside of CGAL::draw().
So, this is what seems appropriate to me:
making SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> a (main or child) widget in OPs Qt application.
I then walked a bit through the github repo to find out from which Qt widget CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> is actually derived from and found the following inheritance:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
So, CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> can be used like any QWidget (which involves making it the main window). It can become as well the center widget of a QMainWindow which gets a menu bar/tool bar with the QAction to open the QFileDialog, request a file path, open a file stream with this file path, and load a mesh from this file stream.
There is another minor detail where I stumbled over: The CGAL::Polyhedron has to be given to the CGAL::SimplePolyhedronViewerQt in the constructor and by const reference. To consider this, it's IMHO necessary (after successful loading of mesh) to construct the CGAL::SimplePolyhedronViewerQt instance by new and set/add it to parent widget afterwards. If this is not acceptable it's probably necessary to go even deeper and replace the CGAL::SimplePolyhedronViewerQt by an own implementation, using the source code of the former as “cheat-sheet”.
This is how such an application could look like:
#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();
}
Please, take this with a “grain of salt” – I've no CGAL at hand and couldn't compile/test the above code.
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
|
show 6 more comments
CGAL::draw() already handles the Qt stuff. You are trying to open a mainwindow in another one. Just call CGAL::draw(mesh) in your main() function without anything else and it will work.
EDIT: Which is exactly what Sheff explained in a much more detailed way.
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53298405%2frunning-draw-polygon-example-in-cgal-package-in-qt-widget-application%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'm using Qt5 in daily business, and once considered CGAL as possible application base (without going further into this direction – not yet). Hence, this question made me curious.
I digged through the source code of CGAL on github and found out why the error message
QCoreApplication::exec: The event loop is already running
occurs.
For this, I copied the relevant lines from 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",""};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
Looking at this source code, it becomes obvious that CGAL::draw() is a small ful-featured Qt application in itself which establishs its own QApplication instance. The OP in turn tried to embed the CGAL::draw() in her/his own Qt application. It is not allowed to instance any derivates of QCoreApplication more than once (according to Qt doc. of QApplication):
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.
(Emphasizing not mine.)
The CGAL doc. provides an (even shorter) example in Polyhedron/draw_polyhedron.cpp to do this right:
#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;
}
but there is no place to insert the QFileDialog at the right point.
Hence, CGAL::draw() is the wrong tool for what OP (probably) intends to do – embed CGAL polyhedron rendering into a Qt application. For this, it is necessary to use the things directly which are called somewhere inside of CGAL::draw().
So, this is what seems appropriate to me:
making SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> a (main or child) widget in OPs Qt application.
I then walked a bit through the github repo to find out from which Qt widget CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> is actually derived from and found the following inheritance:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
So, CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> can be used like any QWidget (which involves making it the main window). It can become as well the center widget of a QMainWindow which gets a menu bar/tool bar with the QAction to open the QFileDialog, request a file path, open a file stream with this file path, and load a mesh from this file stream.
There is another minor detail where I stumbled over: The CGAL::Polyhedron has to be given to the CGAL::SimplePolyhedronViewerQt in the constructor and by const reference. To consider this, it's IMHO necessary (after successful loading of mesh) to construct the CGAL::SimplePolyhedronViewerQt instance by new and set/add it to parent widget afterwards. If this is not acceptable it's probably necessary to go even deeper and replace the CGAL::SimplePolyhedronViewerQt by an own implementation, using the source code of the former as “cheat-sheet”.
This is how such an application could look like:
#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();
}
Please, take this with a “grain of salt” – I've no CGAL at hand and couldn't compile/test the above code.
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
|
show 6 more comments
I'm using Qt5 in daily business, and once considered CGAL as possible application base (without going further into this direction – not yet). Hence, this question made me curious.
I digged through the source code of CGAL on github and found out why the error message
QCoreApplication::exec: The event loop is already running
occurs.
For this, I copied the relevant lines from 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",""};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
Looking at this source code, it becomes obvious that CGAL::draw() is a small ful-featured Qt application in itself which establishs its own QApplication instance. The OP in turn tried to embed the CGAL::draw() in her/his own Qt application. It is not allowed to instance any derivates of QCoreApplication more than once (according to Qt doc. of QApplication):
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.
(Emphasizing not mine.)
The CGAL doc. provides an (even shorter) example in Polyhedron/draw_polyhedron.cpp to do this right:
#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;
}
but there is no place to insert the QFileDialog at the right point.
Hence, CGAL::draw() is the wrong tool for what OP (probably) intends to do – embed CGAL polyhedron rendering into a Qt application. For this, it is necessary to use the things directly which are called somewhere inside of CGAL::draw().
So, this is what seems appropriate to me:
making SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> a (main or child) widget in OPs Qt application.
I then walked a bit through the github repo to find out from which Qt widget CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> is actually derived from and found the following inheritance:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
So, CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> can be used like any QWidget (which involves making it the main window). It can become as well the center widget of a QMainWindow which gets a menu bar/tool bar with the QAction to open the QFileDialog, request a file path, open a file stream with this file path, and load a mesh from this file stream.
There is another minor detail where I stumbled over: The CGAL::Polyhedron has to be given to the CGAL::SimplePolyhedronViewerQt in the constructor and by const reference. To consider this, it's IMHO necessary (after successful loading of mesh) to construct the CGAL::SimplePolyhedronViewerQt instance by new and set/add it to parent widget afterwards. If this is not acceptable it's probably necessary to go even deeper and replace the CGAL::SimplePolyhedronViewerQt by an own implementation, using the source code of the former as “cheat-sheet”.
This is how such an application could look like:
#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();
}
Please, take this with a “grain of salt” – I've no CGAL at hand and couldn't compile/test the above code.
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
|
show 6 more comments
I'm using Qt5 in daily business, and once considered CGAL as possible application base (without going further into this direction – not yet). Hence, this question made me curious.
I digged through the source code of CGAL on github and found out why the error message
QCoreApplication::exec: The event loop is already running
occurs.
For this, I copied the relevant lines from 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",""};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
Looking at this source code, it becomes obvious that CGAL::draw() is a small ful-featured Qt application in itself which establishs its own QApplication instance. The OP in turn tried to embed the CGAL::draw() in her/his own Qt application. It is not allowed to instance any derivates of QCoreApplication more than once (according to Qt doc. of QApplication):
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.
(Emphasizing not mine.)
The CGAL doc. provides an (even shorter) example in Polyhedron/draw_polyhedron.cpp to do this right:
#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;
}
but there is no place to insert the QFileDialog at the right point.
Hence, CGAL::draw() is the wrong tool for what OP (probably) intends to do – embed CGAL polyhedron rendering into a Qt application. For this, it is necessary to use the things directly which are called somewhere inside of CGAL::draw().
So, this is what seems appropriate to me:
making SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> a (main or child) widget in OPs Qt application.
I then walked a bit through the github repo to find out from which Qt widget CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> is actually derived from and found the following inheritance:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
So, CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> can be used like any QWidget (which involves making it the main window). It can become as well the center widget of a QMainWindow which gets a menu bar/tool bar with the QAction to open the QFileDialog, request a file path, open a file stream with this file path, and load a mesh from this file stream.
There is another minor detail where I stumbled over: The CGAL::Polyhedron has to be given to the CGAL::SimplePolyhedronViewerQt in the constructor and by const reference. To consider this, it's IMHO necessary (after successful loading of mesh) to construct the CGAL::SimplePolyhedronViewerQt instance by new and set/add it to parent widget afterwards. If this is not acceptable it's probably necessary to go even deeper and replace the CGAL::SimplePolyhedronViewerQt by an own implementation, using the source code of the former as “cheat-sheet”.
This is how such an application could look like:
#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();
}
Please, take this with a “grain of salt” – I've no CGAL at hand and couldn't compile/test the above code.
I'm using Qt5 in daily business, and once considered CGAL as possible application base (without going further into this direction – not yet). Hence, this question made me curious.
I digged through the source code of CGAL on github and found out why the error message
QCoreApplication::exec: The event loop is already running
occurs.
For this, I copied the relevant lines from 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",""};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
Looking at this source code, it becomes obvious that CGAL::draw() is a small ful-featured Qt application in itself which establishs its own QApplication instance. The OP in turn tried to embed the CGAL::draw() in her/his own Qt application. It is not allowed to instance any derivates of QCoreApplication more than once (according to Qt doc. of QApplication):
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.
(Emphasizing not mine.)
The CGAL doc. provides an (even shorter) example in Polyhedron/draw_polyhedron.cpp to do this right:
#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;
}
but there is no place to insert the QFileDialog at the right point.
Hence, CGAL::draw() is the wrong tool for what OP (probably) intends to do – embed CGAL polyhedron rendering into a Qt application. For this, it is necessary to use the things directly which are called somewhere inside of CGAL::draw().
So, this is what seems appropriate to me:
making SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> a (main or child) widget in OPs Qt application.
I then walked a bit through the github repo to find out from which Qt widget CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> is actually derived from and found the following inheritance:
CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
|
V
CGAL::Basic_viewer_qt
|
V
CGAL::QGLViewer
|
+--------------+--------------+
| |
V V
QOpenGLWidget QOpenGLFunctions
So, CGAL::SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> can be used like any QWidget (which involves making it the main window). It can become as well the center widget of a QMainWindow which gets a menu bar/tool bar with the QAction to open the QFileDialog, request a file path, open a file stream with this file path, and load a mesh from this file stream.
There is another minor detail where I stumbled over: The CGAL::Polyhedron has to be given to the CGAL::SimplePolyhedronViewerQt in the constructor and by const reference. To consider this, it's IMHO necessary (after successful loading of mesh) to construct the CGAL::SimplePolyhedronViewerQt instance by new and set/add it to parent widget afterwards. If this is not acceptable it's probably necessary to go even deeper and replace the CGAL::SimplePolyhedronViewerQt by an own implementation, using the source code of the former as “cheat-sheet”.
This is how such an application could look like:
#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();
}
Please, take this with a “grain of salt” – I've no CGAL at hand and couldn't compile/test the above code.
edited Nov 17 '18 at 23:30
answered Nov 14 '18 at 11:38
ScheffScheff
7,82021325
7,82021325
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
|
show 6 more comments
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
@n.m Did you try this sample code? Please, drop a comment if you cannot compile it. I did it carefully but, nevertheless, the compiler usually finds something to complain about.
– Scheff
Nov 15 '18 at 7:13
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
thanks a lot for your effort @Scheff
– n.m
Nov 15 '18 at 10:54
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
@n.m I read this as: You got it running? Nice to hear.
– Scheff
Nov 15 '18 at 10:55
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
unfortunately I still have a problem in using SimplePolyhedronViewerQt<Polyhedron, ColorFunctor> ,it cannot be used as a type
– n.m
Nov 15 '18 at 11:10
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
qWin.setCentralWidget( new SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>( qWin, mesh, "Basic Polyhedron Viewer", false, fColor));
– n.m
Nov 15 '18 at 11:13
|
show 6 more comments
CGAL::draw() already handles the Qt stuff. You are trying to open a mainwindow in another one. Just call CGAL::draw(mesh) in your main() function without anything else and it will work.
EDIT: Which is exactly what Sheff explained in a much more detailed way.
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
add a comment |
CGAL::draw() already handles the Qt stuff. You are trying to open a mainwindow in another one. Just call CGAL::draw(mesh) in your main() function without anything else and it will work.
EDIT: Which is exactly what Sheff explained in a much more detailed way.
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
add a comment |
CGAL::draw() already handles the Qt stuff. You are trying to open a mainwindow in another one. Just call CGAL::draw(mesh) in your main() function without anything else and it will work.
EDIT: Which is exactly what Sheff explained in a much more detailed way.
CGAL::draw() already handles the Qt stuff. You are trying to open a mainwindow in another one. Just call CGAL::draw(mesh) in your main() function without anything else and it will work.
EDIT: Which is exactly what Sheff explained in a much more detailed way.
answered Nov 15 '18 at 8:31
mgimenomgimeno
1214
1214
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
add a comment |
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
it's working in main() but I want to use it in a GUI application so I want to use it in a method and call it
– n.m
Nov 15 '18 at 11:15
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
You cannot do that. You'll have to extract the significant code from Surface_mesh/include/CGAL/draw_surface_mesh.h and GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h and adapt it to your application.
– mgimeno
Nov 15 '18 at 15:06
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53298405%2frunning-draw-polygon-example-in-cgal-package-in-qt-widget-application%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown