QApplication::processEvents never returns - event-handling

In my application I need to wait until external program (using QProcess) is finished. I want to keep the application responsible so blocking methods are unacceptable.
Also I need to disallow user input. I've tried to make QEventLoop and exec it with QEventLoop::ExcludeUserInputEvents flag, but as documentation says it only delays an event handling:
the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag.
So I implemented simple event filter and install it on qApp (the idea is took from Qt Application: Simulating modal behaviour (enable/disable user input)). It works well, but sometimes QApplication::processEvents function never returns even if I specify the maximum timeout. Could anyone help me to understand for what reasons it periodically happens?
class UserInputEater : public QObject
{
public:
bool eventFilter(QObject *object, QEvent *event)
{
switch(event->type())
{
case QEvent::UpdateRequest:
case QEvent::UpdateLater:
case QEvent::Paint:
return QObject::eventFilter(object, event);
default:
return true;
}
}
};
-
UserInputEater eventEater;
qApp->installEventFilter(&eventEater);
QProcess prc;
prc.start("...");
while(!prc.waitForFinished(10))
{
if(qApp->hasPendingEvents())
{
// Sometimes it never returns from processEvents
qApp->processEvents(QEventLoop::AllEvents, 100);
}
}
qApp->removeEventFilter(&eventEater);
UPD: Seems like it depends of the timeout value for QProcess::waitForFinished.

I guess you are filtering some useful events (for example, QEvent::SockAct could be involved). Try to add some debug output and find out which event types you're actually filtering. Or it might be better to specify the black list of events you want to block instead of white list of events you want to allow. See this answer.
Also you shouldn't use return QObject::eventFilter(object, event);. You should use return false. All other event filters will be called automatically.
This solution however seems weird and unreasonable to me because you can just call setEnabled(false) for your top level widget to block user input, and then you can use QApplication::processEvents without any flags.

Related

Gstreamer 1.0 Pause signal

I need to detect when the current playing audio/video is paused. I cannot find anything for 1.0. My app is a bit complex but here is condensed code
/* This function is called when the pipeline changes states. We use it to
* keep track of the current state. */
static void state_changed_cb(GstBus *bus, GstMessage *msg, CustomData *data)
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
if(GST_MESSAGE_SRC(msg) == GST_OBJECT(data->playbin))
{
g_print("State set to %s\n", gst_element_state_get_name(new_state));
}
}
gst_init(&wxTheApp->argc, &argv);
m_playbin = gst_element_factory_make("playbin", "playbin");
if(!m_playbin)
{
g_printerr("Not all elements could be created.\n");
exit(1);
}
CustomData* data = new CustomData(xid, m_playbin);
GstBus *bus = gst_element_get_bus(m_playbin);
gst_bus_set_sync_handler(bus, (GstBusSyncHandler) create_window, data, NULL);//here I do video overly stuffs
g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, &data);
What do I do wrong? I cannot find working example on connecting such events on Gstreamer 1.0 and 0.x seems a bit different than 1.0 so the vast exaples there don't help
UPDATE
I have found a way to get signals. I run wxWidgets timer with 500ms time span and each time timer fires I call
GstMessage* msg = gst_bus_pop(m_bus);
if(msg!=NULL)
{
g_print ("New Message -- %s\n", gst_message_type_get_name(msg->type));
}
Now I get a lot of 'state-change' messages. Still I want to know if that message is for Pause or Stop or Play or End of Media (I mean way to differentiate which message is this) so that I can notify the UI.
So while I get signals now, the basic problem, to get specific signals, remains unsolved.
You have to call gst_bus_add_signal_watch() (like in 0.10) to enable emission of the signals. Without that you can only use the other ways to get notified about GstMessages on that bus.
Also just to be sure, you need a running GLib main loop on the default main context for this to work. Otherwise you need to do things a bit different.
For the updated question:
Check the documentation: gst_message_parse_state_changed() can be used to parse the old, new and pending state from the message. This is also still the same as in 0.10. From the application point of view, and conceptionally nothing much has changed really between 0.10 and 1.0
Also you shouldn't do this timeout-waiting as it will block your wxwidget main loop. Easiest solution would be to use a sync bus handler (which you already have) and dispatch all messages from there to some callback on the wxwidget main loop.

How to mimic the enyo.Popup behavior

I am currently trying to mimic the enyo.Popup behavior. I looked at the source at github but having a hard time to understand it.
Especially that is the code I have trouble with:
handlers: {
//...
onRequestShow: "requestShow",
onRequestHide: "requestHide"
},
//* #public
events: {
//* Fires after the popup is shown.
onShow: "",
//* Fires after the popup is hidden.
onHide: ""
},
And some where else in the code, there are calls to this.show().
Firstly, I did not found a declaration for this.show(). Secondly, though I assume that it must be inside this.show() and this.hide() respectively, where are the onShow and onHide events called?
And lastly, I defined a kind of myself, containing also the above code. But despite the show() and hide() methods are working, my own requestShow() and requestHide() methods were not called.
What am I missing?
Firstly, show is a function declared on enyo.Control: http://enyojs.com/api/#enyo.Control::show
onShow and onHide are events that can be subscribed to by the popup's owner (hence, their declaration in the events block). They are called in the showingChanged function. The method for calling events is do{EventNameWithoutOn}. In this case: doShow.
Check this documentation on events: https://github.com/enyojs/enyo/wiki/Event-Handling
(Or, you could buy my nice Enyo book! http://roysutton.com/2013/01/31/print-book-now-available/ )
The handlers block is a way for a control to subscribe to messages it (or its children) generate. Having said that, I don't see any place in the code that generates onRequestHide events.
I hope that helps!

How to use the new BufferWithTimeOrCount in Rx that returns IObservable<IObservable<T>> instead of IObservable<IList<T>>

On Windows Phone 7 there is a new version of the BufferWithTimeOrCount extension method for IObservable that returns a "stream of streams" instead of the previous "stream of lists". I'm having difficulty trying to use either the new or old methods, so maybe I just don't understand how it works, but my goal is to create a stream that only fires when an existing stream matches a specified time based pattern during the previous 2 touch events. So far I have created streams for TouchUp and TouchDown (see related question) and In pseudo code I want something like:
//BufferLast2 should contain the last 1 or 2 touch events that occurred in the last 500ms. If no touches occurred this should return an empty set
var BufferLast2 = TouchDown.Merge(TouchUp).BufferWithTimeOrCount(TimeSpan.FromSeconds(0.5), 2);
//Use BufferLast2 to detect tap (TouchDown then TouchUp occuring in less than 0.5s)
var TouchTap = from touch2 in BufferLast2
where touch2.Count == 2 && touch2.First().Action == TouchAction.Down && touch2.Last().Action == TouchAction.Up
select touch2.First(); //returns initial TouchDown event
//Use BufferLast2 to detect Hold (TouchDown with no TouchUp occuring in 0.5s)
var TouchHold = from touch2 in BufferLast2
where touch2.Count == 1 && touch2.First().Action == TouchAction.Down
select touch2.First(); //returns initial TouchDown event
When using the "Stable" Microsoft.Phone.Reactive version of Rx that is built into the ROM calling IObservable<Class>.BufferWithTimeOrCount(...) returns a IObservable<IList<Class>>, which is pretty easy to work with using the standard list operators (as outlined above), but for some reason BufferLast2 was always returning two down events instead of the Down->Up sequence that I expected.
I figured it might be a bug in the code, so I tried adding a reference to the latest version of Rx and used the Observable Extensions from C:\Program Files (x86)\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2838.0\WP7\System.Reactive.dll in which BufferWithTimeOrCount(...) returns a IObservable<IObservable<Class>>. This makes simple filters like Where x.Count == 2 or Where x.First().P == ... much harder to write. I haven't actually figured out how to do a simple filter like x.Count() == 2 on this return value without creating a completely separate subscription or Subject object, which seams way too complex. It's probably a simple error like my last question (all I needed was a Where clause :-P) but it is really driving me bonkers. Any help?
Changing the api makes the buffering look more Rx-y and fits with their Window operator implementation (wouldn't be surprised if using reflector you'd be able to see the Buffer operators using Window). I would think there's probably a variety of reasons that they've changed it. I'm not going to second guess them as they're a lot smarter than me!
So here's my stab at a solution. There may be a cleaner way to get what you're after but i'd probably implement my own extention method to buffer into a list. Maybe something like:
public static class BufferToList
{
public static IObservable<IEnumerable<TSource>> BufferToList<TSource>(this IObservable<TSource> source)
{
return Observable.CreateWithDisposable<IEnumerable<TSource>>(observer =>
{
var list = new List<TSource>();
return source.Subscribe(list.Add,
observer.OnError,
() =>
{
observer.OnNext(list);
observer.OnCompleted();
});
});
}
}
Then something like:
TouchDown.Merge(TouchUp)
.BufferWithTimeOrCount(TimeSpan.FromSeconds(0.5), 2)
.Select(bufferedValues => bufferedValues.BufferToList())
.Subscribe(OnBufferOpen)
private void OnBufferOpen(IObservable<IEnumerable<IEvent<IEventArgs>>> bufferedListAsync)
{
bufferedListAsync.Where(list => list.Count() == 2);
}
I suggest if you want a full explanation of why they've changed the api, go and ask the question over on the rx forums on msdn
The latest release of Rx, v1.0.2856.0, provides both buffers and windows. For the buffers, we restored the original signatures, based on IList. The corresponding window operators will return nested observable sequences.
The way the Buffer* operators are implemented is by composing the corresponding Window* operator with the new ToList extension method that takes an IObservable into an IObservable>. All the Buffer* operator does is invoke this new ToList operator in a SelectMany selector.

pause viewmodel process for user input

I've been looking at a view examples of the typical "raise dialog from viewmodel" problem, noting 3 main solutions:
use attached behaviors
use a mediator pattern
use a service
I'm getting a bit bogged down though and struggling to find a solution that easily fits into my problem space - which is a very simple file copy problem:
My viewmodel is processing a loop (copying a list of files)
When a file already exists at the destination I need to raise a modal dialog to get confirmation to replace
The vm needs to wait for and receive confirmation before continuing
The "modal dialog" is actually not a new window but a hidden overlay in my MainWindow, as per http://www.codeproject.com/KB/WPF/wpfmodaldialog.aspx (thanks Ronald!)
I'm mostly there but the biggest struggles I have are:
- how to pause the loop in the viewmodel while it waits for input
- how to get input back to the viewmodel within the loop so it can carry on
So far I'm leaning towards the service solution because it seems a direct method call with a return that the vm must wait for. However, it does mean the service needs to tie directly to the view in order to make an element visible?
If anyone can post some simple code that deals directly with this problem I (and the net) would be very happy! Thanks!
For example, you have a service called IDialogService with the following interface:
public interface IDialogService
{
bool ConfirmAction(string title, string confirmationText);
}
As you mentioned, in order for the service to be able to show the actual dialog it needs to have a reference to the view that will show the actual overlay element. But instead of directly referencing the view I prefer to reference it via an interface. Lets call it ICanShowDialog and it will have the following members:
public interface ICanShowDialog
{
void ShowDialog(object dialogContent);
void HideDialog();
}
This interface will be implemented by your view that owns the dialog overlay (e.g. your main window).
Now the interesting part: suspending the code execution while the dialog is shown. First of all, I would recommend you not to use overlay elements but use usual windows if possible. Then you will not have that problem. You can style the dialog window so it will look just like the overlay element.
Anyway, if you still want to use overlay elements then you can do the following trick to suspend the code execution:
Here is pseudo code of the ConfirmAction method of the IDialogService inteface:
public bool ConfirmAction(string title, string confirmationText)
{
ConfirmationDialogView dialogView = new ConfirmationDialogView(title, confirmationText);
DialogShower.ShowDialog(dialogView); // DialogShower is of type ICanShowDialog
while (!dialogView.ResultAvailable)
{
DispatcherUtils.DoEvents();
}
DialogShower.HideDialog();
return dialogView.Result;
}
Here is the code of DispatcherUtils.DoEvents() (that was taken from here: http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html):
public static class DispatcherUtils
{
public static void DoEvents()
{
DispatcherFrame f = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Background,
(SendOrPostCallback)delegate(object arg) {
DispatcherFrame fr = arg as DispatcherFrame;
fr.Continue=True;
}, f);
Dispatcher.PushFrame(frame);
}
}
But I must warn you. Using DoEvents can result in some subtle bugs caused by inner dispatcher loops.
As an alternative to suspending the code execution while a dialog is shown you can use callbacks:
public interface IDialogService
{
void ConfirmAction(string title, string confirmationText, Action<bool> dialogResultCallback);
}
But it will not be so convenient to use.

What is better approach to wait for elements on a page Waitforcomplete() or system.threading.thread.sleep()

I am Using WaitforComplete() in watiN but it doesnt seems to work well. As it executes the next statement even if you have given longer time to wait. I am using thread.sleep() to stop my application until it gets the desired page or element. But the thing is pages are so much dynamic that sometimes it takes much longer time as specified.
Any better solution. Any thing that will catch the page return dynamically and dont go to execute next statments in application.
Sample of Code
'Show Details page
Assert.AreEqual("Confirmation", _internetExplorer.Title)
If (_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Exists) Then
_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Click()
Else
Assert.Fail("Could not Find Finish Booking Button on Confirmation Page")
End If
System.Threading.Thread.Sleep(100000)
'Show Booking Summary page
Assert.AreEqual("Display Booking", _internetExplorer.Title)
I want something that detect the return of page dynamically. instead of giving some constant value.
WaitForComplete only works well if there is a postback after some action. Otherwise you have to find something else to wait for. Following an example on how to wait for the specified title:
_internetExplorer.Element("title", "Confirmation").WaitUntilExists();
I would always prefer to use one of the WaitXXX methods instead of Thread.Sleep cause the WaitXXX methods do only wait until the contraint is met. Where as Sleep waits for the time you specified. If its to long, time is waisted. If its to short, problems arise.
HTH,
Jeroen
The WaitForComplete method esentially moves on once the browser has set it's readystate to comllete and the busy state to false.
What I typically do is to try and access what you need to, then perform a thread.sleep for say half a second, then try again. I also have a global timeout that quits after say 10 seconds.
int timeout = 20;
bool controlFound = false;
for (int i = 0; i < timeout; i++)
{
if (_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Exists)
{
_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Click();
controlFound = true;
break;
}
else
{
System.Threading.Thread.Sleep(500);
}
}
if (!controlFound)
{
Assert.Fail("Control not found");
}
If it is executing the next statement, it should be finding the corresponding element. I suggest posting a sample of the code you are trying.