PDA

View Full Version : event loop already running



prkhr4u
5th February 2014, 10:07
I am trying to run a QApplication on button click from Main window.
However I am getting this error:

QCoreApplication::exec: The event loop is already running
My code inside button click is this:

if (!g_thread_supported ())
g_thread_init (NULL);

gst_init (NULL, NULL);
QApplication app(NULL, NULL);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));

// prepare the pipeline

GstElement *pipeline = gst_pipeline_new ("xvoverlay");
GstElement *src = gst_element_factory_make ("souphttpsrc",NULL);
GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
GstElement *jpegdec = gst_element_factory_make("jpegdec",NULL);
//assert(jpegdec);
gst_bin_add_many (GST_BIN (pipeline), src,jpegdec, sink, NULL);
gst_element_link_many(src,jpegdec, sink);

g_object_set (src, "location", "http://169.254.75.39/video2.mjpg", NULL);
// prepare the ui

QWidget window;
window.setWindowFlags(Qt::Window|Qt::FramelessWind owHint);
window.move(0,400);
window.setFixedSize(320, 200);
window.show();

WId xwinid = window.winId();
gst_x_overlay_set_window_handle (GST_X_OVERLAY (sink), xwinid);

// run the pipeline

GstStateChangeReturn sret = gst_element_set_state (pipeline,
GST_STATE_PLAYING);
if (sret == GST_STATE_CHANGE_FAILURE) {
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
// Exit application
QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
}

int ret = app.exec();

window.hide();
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);

I am able to run this code,if I put it after

ui->setupUi(this);
in the MainWindow

How can I resolve this problem?

Lesiok
5th February 2014, 10:36
From QApplication doc : 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. You can not have multiple QApplication objects.

anda_skoa
5th February 2014, 10:41
How does your main() function look like? Do you create and run a QApplication in there already?

Cheers,
_

prkhr4u
5th February 2014, 11:23
My main() function is like this:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

I have created 1 QApplication object there also

anda_skoa
5th February 2014, 12:06
Then this is enough.
Just remove the QApplication stuff from your slot.

Cheers,
_

prkhr4u
6th February 2014, 09:46
I have removed the QApplication stuff from my code.
But now nothing is being shown.No error also.
Here is the modified code:

if (!g_thread_supported ())
g_thread_init (NULL);

gst_init (NULL, NULL);
//QApplication app(NULL, NULL);
//a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit ()));

// prepare the pipeline

GstElement *pipeline = gst_pipeline_new ("xvoverlay");
GstElement *src = gst_element_factory_make ("souphttpsrc",NULL);
GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
GstElement *jpegdec = gst_element_factory_make("jpegdec",NULL);
gst_bin_add_many (GST_BIN (pipeline), src,jpegdec, sink, NULL);
gst_element_link_many(src,jpegdec, sink);
g_object_set (src, "location", "http://169.254.75.39/video2.mjpg", NULL);
// prepare the ui

QWidget window;
window.setWindowFlags(Qt::Window|Qt::FramelessWind owHint);
window.move(1000,480);
window.setFixedSize(320, 200);
window.show();

WId xwinid = window.winId();
gst_x_overlay_set_window_handle (GST_X_OVERLAY (sink), xwinid);

// run the pipeline

GstStateChangeReturn sret = gst_element_set_state (pipeline,
GST_STATE_PLAYING);
if (sret == GST_STATE_CHANGE_FAILURE) {
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
// Exit application
//QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
}

//int ret = a.exec();

window.hide();
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);

Lesiok
6th February 2014, 18:41
I have removed the QApplication stuff from my code.
But now nothing is being shown.No error also.


Because in line 41 You hide new window.

d_stranz
7th February 2014, 01:05
Because in line 41 You hide new window.

Worse than that. The window is created on the stack in line 19, so as soon as control exits the if() clause starting on line 1, the window goes out of scope and is destroyed. Poof! Now you see it, now you don't!

prkhr4u
7th February 2014, 07:12
@Lesiok I agree with your fact that only one QApplication object can be formed , but can you explain how in this case I am able to make 2 QApplication object and run it.
Here is the code:

//main.cpp

QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();

//mainwindow.cpp

ui->setupUi(this);
if (!g_thread_supported ())
g_thread_init (NULL);

gst_init (NULL, NULL);
QApplication app(NULL, NULL);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));

// prepare the pipeline

GstElement *pipeline = gst_pipeline_new ("xvoverlay");
GstElement *src = gst_element_factory_make ("souphttpsrc",NULL);
GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
GstElement *jpegdec = gst_element_factory_make("jpegdec",NULL);
//assert(jpegdec);
gst_bin_add_many (GST_BIN (pipeline), src,jpegdec, sink, NULL);
gst_element_link_many(src,jpegdec, sink);
g_object_set (src, "location", "http://169.254.75.39/video2.mjpg", NULL);
// prepare the ui

QWidget window;
window.move(0,0);
window.resize(320, 240);
window.show();

WId xwinid = window.winId();
gst_x_overlay_set_window_handle (GST_X_OVERLAY (sink), xwinid);

// run the pipeline

GstStateChangeReturn sret = gst_element_set_state (pipeline,
GST_STATE_PLAYING);
if (sret == GST_STATE_CHANGE_FAILURE) {
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
// Exit application
QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
}

int ret = app.exec();

I am able to run successfully and able to get the desired output.


Added after 12 minutes:

I have made some changes and am still unable to get the QWidget window.Here is my code on button click event:

gst_init (NULL, NULL);
// prepare the pipeline

GstElement *pipeline = gst_pipeline_new ("xvoverlay");
GstElement *src = gst_element_factory_make ("souphttpsrc",NULL);
GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
GstElement *jpegdec = gst_element_factory_make("jpegdec",NULL);

gst_bin_add_many (GST_BIN (pipeline), src,jpegdec, sink, NULL);
gst_element_link_many(src,jpegdec, sink);
gst_element_set_state(sink, GST_STATE_READY);
g_object_set (src, "location", "http://169.254.75.39/video2.mjpg", NULL);

// prepare the ui
QWidget widg1;
widg1.move(0,0);
widg1.setFixedSize(320,200);
widg1.show();

WId xwinid = widg1.winId();
QApplication::syncX();
gst_x_overlay_set_window_handle (GST_X_OVERLAY (sink), xwinid);

GstStateChangeReturn sret = gst_element_set_state (pipeline,
GST_STATE_PLAYING);
if (sret == GST_STATE_CHANGE_FAILURE) {
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
}

After debugging, I found that an empty QWidget window is created after QApplication::syncX(),but is destroyed as it exits the function.
Also the State is changing successfully as it does not enter the if condition and directly exit.

What should I do to retain the window and successfully overlay the gstreamer stream over it??

Lesiok
7th February 2014, 08:25
What you really want to do ?

anda_skoa
7th February 2014, 09:10
What should I do to retain the window and successfully overlay the gstreamer stream over it??

C++ basics: if you want an object to live across a block scope boundary, create it on the heap.

As d_stranz already wrote but which you seem to have ignored: you create widg1 on the stack inside the block scope of an if(). It is destroyed when the scope ends.

Cheers,
_

prkhr4u
7th February 2014, 11:36
@Lesiok,I want to create a QWidget to play a video stream using gstreamer on button click event.
But pl tell how are 2 QApplication objects created in the above example ??

@anda_skoa, point noted. Sorry I neglected the stack point
I will try to create the QWidget on the heap and see if it persists.

Lesiok
7th February 2014, 11:50
@Lesiok,I want to create a QWidget to play a video stream using gstreamer on button click event.
But pl tell how are 2 QApplication objects created in the above example ??


So create QWidget on heap (i.e. with new opeartor) and show them. That is all. You don't need next QApplication.
You are making a mistake like many others here : trying to use an extensive library (Qt) without knowing the basics of programming language (C++).

prkhr4u
12th February 2014, 04:15
Thank You all,the issue has been solved.
I used declared QWidget like this:

QWidget *wid = new QWidget(this);