Process Codes in the Middle of a SequentialTransition- JavaFX - javafx

I am trying to execute a SequentialTransition, but between the animations, I need to execute some commands.
My problem is that it is always executing the last commands passed on the node. Is there any way to fix this?
Where is "is ignored" is the code that I need to be executed in the first animation, then where this "is executed" is the code that I need to be executed in the second animation.
Thanks
private void startAnimation(){
vb_adv.setPrefWidth(197);
ap_services.toBack();// Is ignored
vb_adv.toFront();// Is ignored
ScaleTransition expandAdvertising = new ScaleTransition(Duration.millis(2000), vb_adv);
expandAdvertising.setToX(2);
expandAdvertising.setCycleCount(2);
expandAdvertising.setAutoReverse(true);
ap_services.setPrefWidth(124);
ap_services.toFront();//is executed
ScaleTransition expandService = new ScaleTransition(Duration.millis(2000), ap_services);
expandService.setDelay(Duration.seconds(3));
expandService.setToX(3.7);
expandService.setCycleCount(2);
expandService.setAutoReverse(true);
SequentialTransition sequence = new SequentialTransition(expandAdvertising, expandService);
sequence.play();
}

In the code as you currently have it, you move ap_services to the back of the z-order, and vb_adv to the front:
ap_services.toBack();
vb_adv.toFront();
Then you create and set up you ScaleTransition. Note that doing this part takes essentially no time; all you are doing is configuring the animation which will run later.
The next thing you do is to move ap_services to the front:
ap_services.toFront();
Note that this will happen essentially immediately after the previous calls to toFront() and toBack(), and of course this negates the effect of those calls. So your initial calls are actually executed (not "ignored"), but you immediately do something which undoes their effect.
What you really want is to execute ap_services.toFront() after the ScaleTransition finishes. You can do this by putting that call in an onFinished() handler:
// ap_services.toFront();
expandAdvertising.setOnFinished(e -> ap_services.toFront());

Related

How to realize a prompt dialog box when load a large file or other things using Qt?

I need to load a large file to parse and draw with OpenGL. The whole process is very time-consuming. So I want to realize a prompt dialog box before parse. But the code as following is not work.
void parseFile()
{
QMessageBox* msgbox = new QMessageBox();
msgbox->setModal(false);
msgbox->setWindowTitle(tr("message box"));
msgbox->setText("Please wait patiently......")
msgbox->show();
/* parse file and draw */
......
}
But it shows like also be frozen:
How to realize it?
show() does not actually show the content of the dialog. It only tells the event loop to show the dialog ASAP. But since you call more code after immediately after show(), the evnt loop does not have a chance to do its work.
The easiest way to solve this is to call QCoreApplication::processEvents() after msgbox->show(). This will force the event loop to do the work immediately.
If this does not work then try this parameter QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents)
Another option would be to move the heavy calculation to a function and than show the dialog and then schedule the calculation using a timer.
...
msgbox->show();
QTimer::singleShot(0, &doHeavyWork);
This would first handle all events related to showing the dialog and only after that it will start the heavy work (i.e. parsing the file).

Progress bar change the value but not update the graphic

I try much method i have find to do this, but no one work for me.
I have tried with qApp.processEvents() and with update() but no one work.
void GUI::startLoading(int currentFile) {
ui->progressBar->setValue(currentFile);
ui->progressBar->update();
}
currentFile is an int of the current loaded file from another function.
Here's a screenshot of de dubug that told the current value of the progress bar, but the progress bar don't increment.
Are you doing busy work in the GUI thread? Qt needs to get a chance to process events for the redraw to happen.
update() only enqueues the redraw. Note that setValue() calls update() itself. To avoid this problem, you can call QEventLoop::processEvents() from time to time (e.g. at the same place where you update the progress bar), or use a worker thread.

Moving to the bottom of an element with Webdriver.io

I have a page that has elements that become visible as you scroll down. I am trying to execute a test to make sure the elements are not there until the scroll is to the bottom of the elements, but I can't seem to figure out how to pass the size from one call (elementIdSize()) to the scroll offset of the next call (scroll()). Admittedly my brain does not yet get the concept of "promises" past simple call chaining.
I tried something like this:
this.browser
.setViewportSize({width: 1000, height: 600})
.element(selector)
.then(function(e) {
console.log('then element: ', e);
element = e;
})
.elementIdSize(element.id)
.then(function(size) {
console.log('Size: ', size);
})
.call(callback);
Which I was hoping would use the passed-in selector to get the element, set the element in the then(), then call elementIdSize() on the element's ID, but the var element is never set from the element() call, and the objects I am getting back don't seem to be what I am trying to get anyway. I feel this is some simple piece of knowledge I am missing here that will make all this "click".
I am using the APIs here for looking up the Webdriver calls, but the documentation doesn't give much details.
It's important to understand that all parameters will get resolved once you execute the chain. That means you can't change them anymore once you've executed the first command basically. In your example you set the value of the element variable in a promise callback. At the time you do that, elementIdSize already read the element variable (and probably threw an error).
The proper way to this is to execute commands that have arguments which get resolved at a later time in then or finish routines. You can also save commands in WebdriverIO by using action commands instead of raw protocol commands. So just use getSize instead of call element first and then call elementIdSize. That is the job of getSize ;-)
I am not sure what exactly you try to do but here is the code that should do the trick:
this.browser
.setViewportSize({width: 1000, height: 600})
.getElementSize(selector).then(function(size) {
console.log('size of element "' + selector + " is', size);
// now as we have the size execute the scroll in a then callback
return this.scroll(0, 600 + size.height);
})
// this get executed once we we did the scrolling since
// the getSize promise is only then fulfilled once the promise
// within the then function is resolved
.isVisible(otherElem).should.be.eventually.be(true, 'element was visible after scrolling')
.call(callback);
(As a side note: we already working on WebdriverIO v4 that will allow to execute commands synchronously, so no more promise headaches ;-))

Flex addEventListener - how to refresh the screen during called event?

I can't seem to find the answer to what I would have thought was a common problem.
What I want to do this is:
1. Show the Open File Dialog
2. Process the file selected
3. During processing the file, report progress to the User
I have a file defined, and am using the browseForOpen and AddEventListener:
public var fileInput:File = new File();
fileInput.browseForOpen("Open file",[filter]);
fileInput.addEventListener(Event.SELECT, onFileSelect);
// Step 2 - function gets called to process the file
private function onFileSelect(e:Event):void
{
// Step 3 - do some processing, and at intervals report progress to the screen
}
My issue is - any changes to the screen within the event listener do not get done until the function is complete.
Any help would be appreciated,
Thanks
Start a timer perhaps and let it check status of a variable(that denotes processing progress) as a separate running function it would not be predisposed to waiting on the parent function.
[ to be clear Im saying call a sperate function from the timer.]
But I am inclined to agree with Flextras.com in that most times I have done this the processing was milliseconds so just didnt get seen.
In Step 3, if you are doing some cpu intensive job(like huge xml parsing), then you might be seeing this NOT updating problem. As Flex is single threaded, you better make use of Green threading concept.
You can read about Green Threading here.

problem with QPropertyAnimation in Qt

i have a problem with QPropertyAnimation in Qt
my code:
QString my_text = "Hello Animation";
ui->textBrowser->setText((quote_text));
ui->textBrowser->show();
QPropertyAnimation animation2(ui->textBrowser,"geometry");
animation2.setDuration(1000);
animation2.setStartValue(QRect(10,220/4,1,1));
animation2.setEndValue(QRect(10,220,201,71));
animation2.setEasingCurve(QEasingCurve::OutBounce);
animation2.start();
till now it seems very good , but the problem is that i can see this animation only when i show a message box after it .
QMessageBox m;
m.setGeometry(QRect(100,180,100,50));
m.setText("close quote");
m.show();
m.exec();
when i remove the code of this message box , i can't see the animation anymore.
the functionality of the program doesn't require showing this MessageBox at all.
Can anybody help?
Maybe it is an update problem. Could you try to connect the valueChanged() signal of QPropertyAnimation to an update() call in the GUI?
My guess is that the code for the animation that you present is inside a larger chunk of code where the control doesn't get back to the event loop (or the event loop hasn't started yet). This means that when the MessageBox's exec function is called, an event loop starts operating again, and the animation starts. If you were to dismiss the message box in the middle of the animation, it would probably freeze at that point, as well.
animation2 is declared as a local variable. When the enclosing function
exits, it is no longer in scope and is deleted. The animation never runs as
it does not exist when Qt returns to the event loop and, as noted in the QAbstractAnimation
documentation
(QPropertyAnimation inherits QAbstractAnimation), for QPropertyAnmiation to execute, it must exist when Qt returns to the event loop.
When control reaches the event loop, the animation will run by itself,
periodically calling updateCurrentTime() as the animation progresses.
The solution is to dynamically allocate animation2 rather than declare it as
a local variable.
QPropertyAnimation *animation2 = new QPropertyAnimation(ui->textBrowser,"geometry");
animation2->setDuration(1000);
animation2->setStartValue(QRect(10,220/4,1,1));
animation2->setEndValue(QRect(10,220,201,71));
animation2->setEasingCurve(QEasingCurve::OutBounce);
animation2->start();
Note that this it the same technique is the same as that used in the C++
example provided in the QPropertyAnmiation
documentation:
QPropertyAnimation *animation = new QPropertyAnimation(myWidget, "geometry");
animation->setDuration(10000);
animation->setStartValue(QRect(0, 0, 100, 30));
animation->setEndValue(QRect(250, 250, 100, 30));
animation->start();
The original question notes:
i can see this animation only when i show a message box after it
This is an interesting side affect of how QMessageBox works. The exec()
method executes an event loop. Since the event loop executes within the scope
of the function enclosing animation2, animation2 still exists and the
desired animation executes.
By default, animation2 will be deleted when the parent, ui->textBrowser in
the original question, is deleted. If you wish for the animation to be
deleted when it completes executing, QAbstractAnimation provides a property
that controls when the animation is deleted. To automatically delete
animation2 when it finishes executing, change the start() method to:
animation2->start(QAbstractAnimation::DeleteWhenStopped);

Resources