QInputMethod : programatically end the input method session - qt

I have a QWidget ( lets call it parentWidget ) on which I have enabled the input method by setting the attribute : Qt::WA_InputMethodEnabled.
My interest is to pop up a Line dialog ( lets call it inputMethodEditor ) which should further handle all the input of the text.
Now I have read that the inputMethod works like a session, means it has states like startedToCompose, composing, completing. While the input method is in startedToCompose or composing state it sends the string under composition in preEditString through inputMethodEvent and once the session completes it sends the final composed string in commitString().
My intent is to finish this session started on parentWidget as soon as the inputMethodEditor dialog is popped up.
So, the question is, whether there is a way to close this session programmatically.?

After exploring a while, I could figure it out, I don't know how I overlooked it earlier.
So the trick is to invoke QInputMethod::reset function.
Something like this:
QApplication* application = static_cast<QApplication *>(QApplication::instance());
application->inputMethod()->reset();

Related

Qt pass data between multiple forms

I am new to Qt and understands the concept of signal and slots. However I am not able to implement it.
My objective is:
Form1 has a button Config. So when I click Config it should open another form Form2( without closing Form1) and send a string strData to Form2.
In Form2 I set some value in the string strData. Then I click Ok button in Form2, Form2 should close and return back the string to Form1.
When the call returns back to Form1, it should continue from where it emitted the signal to invoke Form2.
Any help is highly appreciated.
You can't do this using signals/slots; the signal is emitted, and all of the connected slots are executed, and then the code continues from where the signal is emitted and eventually returns to the event loop. That's when your second form is actually shown and the user can respond to it, but by then, your code is long past where the signal was emitted.
What I believe you're looking for is the QDialog::exec method; use it in place of the signal. The basic pattern of the code is:
// This is the response to click on Config...
Form2Dialog form2;
form2.setSomeStringValue (some_value);
if (form2.exec() == QDialog::Accepted)
{
QString some_new_value = form2.newValue();
}
The Form2Dialog is a subclass of QDialog where you've added your own setSomeStringValue and newValue methods. (What you actually name these is up to you.)
The important thing is that the exec method blocks and doesn't return until the user selects OK or Cancel on the dialog, or closes it using the "close" button in the title bar (if there is one).

How to get return value in this case? (Java FX)

I'm writing part of a cross-platform application, where we mostly use REST (jersey) and Hibernate to communicate between systems. I'm new to JavaFX, but my side of the program should use it to get input values from users. Here is how the code flow would look:
public class startingClass{
...
public void startingMethod(Payload payload){
//send REST requests to different places with different payloads, like:
Response response = Utility.sendPostRequest(URI, payload2);
something = response.readEntity(something.class)
//more processing with the returned values
...
}}
In one of the places where I sent a request:
#Path("something")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public class Resource{
...
#POST
#Path(something)
public Response doSomething(Payload payload) {
//show JavaFX window with text fields and an okay button
JavaFXClass.launch(JavaFXClass.class);
/* THIS IS WHERE I would need to get back the input values somehow */
//payload3 has the input values I need to send back
return Response.entity(payload3).build();
}}
The JavaFX class extends application and and overrides the (void) start method where I put together the window I want to show and after the button click (if inputs are okay) I close the window.
So the idea is that the startingMethod would have to wait, until the response comes back (maybe return with some default values, if the user doesnt type in anything for a minute - what would be the elegant solution for that?) with the input values. This would guarantee the sync.
If I use more REST or database saves inside the JavaFX class then I can't be sure the values are there by the time I wanna use them in the startingMethod (probably not) and it's probably a really bad looking solution anyway.
What could I do? I dont know much about callback methods in javafx, can those help me here? Thanks!
In the end I moved the JavaFXClass into the Resource class. Meaning Resource class extends Application, overrides start, etc. In the doSomethingMethod I call launch in a try-catch block, catch the IllegalStateException if needed and call start() instead (also in a try-catch block). The textfield input values are stored in a global variable after.
Also in the start() method I havePlatform.setImplicitExit(false);
so the doSomethingMethod() can be called multiple times without a problem, starting the javaFX window. It's not a pretty solution.

windows should not respond for given duration in c# or silverlight

example- as i clicked on button , output window should come but it should be like blurred or wait for some time (like something is executing in background).. after some time window should be in activate mode.
could you help me to achieve this without using thread.sleep method ?
Then, you could use a stopwatch , set it for the amount of time you need and then disable all controls of your application(Winform?Silverlight?)
Then you just loop until the stopwatch as finished, or display some kind of Processing label.
While(stopwatch.IsRunning)
{
//Do nothing
}
BTW: This is a synchronous operation, if there's something the thread needs to do while user input is on hold you can't use that.

Asynchronous validation in QWizard

I'm writing a wizard UI based on the QWizard Qt object. There's one particular situation where I want the user to log in to a service using host, username, and password. The rest of the wizard then manipulates this service to do various setup tasks. The login may take a while, especially in error cases where the DNS name takes a long time to resolve -- or perhaps it may not even resolve at all.
So my idea is to make all three fields mandatory using the registerField mechanism, and when the user hits Next, we show a little throbber on the wizard page saying "Connecting to server, please wait..." while we try to connect in the background. If the connection succeeds, we advance to the next page. If not, we highlight the offending field and ask the user to try again.
However, I'm at a loss for how to accomplish this. The options I've thought of:
1) Override validatePage and have it start a thread in the background. Enter a wait inside validatePage() that pumps the Qt event loop until the thread finishes. You'd think this was the ugliest solution, but...
2) Hide the real Next button and add a custom Next button that, when clicked, dispatches my long running function in a thread and waits for a 'validation complete' signal to be raised by something. When that happens, we manually call QWizard::next() (and we completely bypass the real validation logic from validatePage and friends.) This is even uglier, but moves the ugliness to a different level that may make development easier.
Surely there's a better way?
It's not as visually appealing, but you could add a connecting page, and move to that page. If the connection succeeds, call next() on the wizard, and if the connection fails, call previous() and highlight the appropriate fields. It has the advantage of being relatively straightforward to code.
My final choice was #2 (override the Next button, simulate its behavior, but capture its click events manually and do the things I want to with it.) Writing the glue to define the Next button's behavior was minimal, and I was able to subclass QWizardPage with a number of hooks that let me run my task ON the same page, instead of having to switch to an interstitial page and worry about whether to go forwards or backwards. Thanks Caleb for your answer though.
I know this has already been answered (a long time ago!) but in case anyone else is having the same challenge. Another method for this is to create a QLineEdit, initiate it as empty and set it as a mandatory registered field. This will mean that "Next" is not enabled until it is filled with some text.
Run your connection task as normal and when it completes use setText to update the QLineEdit to "True" or "Logged in" or anything other than empty. This will then mean the built in isComplete function will be passed as this previously missing mandatory field is now complete. If you never add it to the layout then it won't be seen and the user won't be able to interact with it.
As an example ...
self.validated_field = QLineEdit("")
self.registerField('validated*', self.validated_field)
and then when your login process completes successfully
self.validated_field.setText("True")
This should do it and is very lightweight. Be sure though that you consider the scenario where a user then goes back to that page and whether you need to reset the field to blank. If that's the case then just add in the initialisePage() function to set it back to blank
self.validated_field.setText("")
Thinking about it you could also add the line edit to the display and disable it so that a user cannot update it and then give it a meaningful completion message to act as a status update...
self.validated_field = QLineEdit("")
self.validated_field.setDisabled(True)
self.validated_field.setStyleSheet("border:0;background-color:none")
self.main_layout.addWidget(self.validated_field)
self.registerField('validated*', self.validated_field)
and then when you update it..
self.validated_field.setText("Logged in")

Flex's FileReference.save() can only be called in a user event handler -- how can I get around this?

I need to call FileReference.save() after a web service call has completed, but this method has a restriction: "In Flash Player, you can only call this method successfully in response to a user event (for example, in an event handler for a mouse click or keypress event). Otherwise, calling this method results in Flash Player throwing an Error exception." (from the documentation here)
This restriction is a bit vague. Does it mean that I can only call the FileReference.save() method from within an event handler function that is registered as a listener for certain types of user events? If so then exactly which user events are valid? (Perhaps there's an event that will never be dispatched by user interaction with my application and I could register an event handler function for that event type and make the save() call from within that function?)
My difficulty is that I can't safely call the FileReference.save() method until my web service returns with the data that will be used as the argument of the FileReference.save() method call, so the event that triggers the FileReference.save() call is actually a ResultEvent rather than a user event, and I'm leery of dispatching a new (faux) user event type in order to be able to trigger the FileReference.save() call unless it's definitely a user event that would never be dispatched as a result of actual user interaction with my application.
In a nutshell what I'm doing now is this: I have a function that is registered as a handler for a button click. In this function I make my web service call to fetch data from the server. I also have a result handler function which gets invoked when the web service call completes, and it's in here that I want to call the FileReference.save() method since it's at this point that I know that the data is ready to be saved to a file. But the aforementioned restriction is blocking me from doing this -- I get an error:
Error #2176: Certain actions, such as those that display a pop-up window,
may only be invoked upon user interaction, for example by a mouse click
or button press.
I've tried many things to get around this such as creating a second mouse click event handler function with the FileReference.save() call within and calling it after a timeout interval (to give the web service time to complete), but I keep running into the same error -- maybe that approach doesn't work since the second function isn't registered as an event listener for the event type used as its argument.
I'm new to Flex development so perhaps I'm just not thinking about this in the right way. If anyone can suggest another approach I'd really appreciate it. Thanks in advance for your comments or suggestions.
--James
Adobe does this as a sort of security measure to ensure users are the ones messing with files rather than potentially harmful code. My understanding is that they enforce this by only allowing handlers of (click?) events that originate from UI components to execute the FileReference methods, so generating your own events programmatically will not work, although I have not tried to verify this. Unfortunately the best resolution I've found is to re-work the UI a bit to conform to this constraint. In your particular situation, you could make this a two click process with a button that says something like "Prepare Download", which changes to "Download File" after the web service is complete. This is less than ideal from a user perspective, but I don't think there's much else that can be done unless you can somehow complete your web service call prior to displaying the button that triggers the FileReference.save() call.
After struggling for that for well, a couple hours I found a workaround: you can use both mouseDown AND mouseUp events instead of just click.
For instance:
s:Button
mouseDown="prepare_PDF()"
mouseUp="save_PDF()"
Works fine for me!
Happy coding!
--Thomas
As a workaround I used the ExternalInterface class. I created a javascript function with this code
function downloadFile (url) {
window.open(url);
}
An in AS3 I call
var url = 'www.example.com/downloadfile.php?file_id=xxx';
ExternalInterface.call('downloadAttachmentFile', url);
So with that I transfer the file handling to JS/HTML.
This is a comment on Thomas' answer (I don't have enough XP to comment yet): The mousedown and mouseup workaround works nicely. Just a note that if you make any changes in prepare_PDF() that need 'undoing' in save_PDF(), then its a good idea to call that code on the mouseout event as well, since there might be a case that the user mousedown's on the button, but then moves the mouse away from the button.
This was particularly relevant for my case, in which we increase the size of a watermark on an image when the user clicks the download button (that triggers the .save() call). I reduce the size of the watermark down to normal on the mousedown and mouseout events.
I had this same issue, I chose to use flash.net methods. Call flash.net.navigateToURL(url); from an actionscript or navigateToURL(url); from mxml.
What i do to solve this is to show an alert message with an anonymous function so i don't have to create a button.
Alert.show("Do you wish to download the file?", "Confirm", Alert.OK | Alert.CANCEL, this, function (eventObj:CloseEvent):void {
if (eventObj.detail == Alert.OK) {
fileReference.save(zipOut.byteArray, dateFormater_titulo.format(new Date ()) + ".zip");
}//if
}/*function*/, null, Alert.OK);

Resources