Kivy-Image only centered some of the time at run time - image

i have a GridLayout with a Button and an image to display inside the Button. when i run my app the Image in the button sometimes centers and sometimes it don't. why? i believe it should always be centered.
.kv file:
MyLayout:
cols: 2
height: self.minimum_height
pos: root.pos
Button:
size_hint_y: None
height: self.parent.width/2
Image:
source: 'Images/employee/userprofile.png'
size: self.parent.size
center_x: self.parent.center_x
center_y: self.parent.center_y
the following image is what I expect every time:
this is what I get sometimes:

This is a common issue with alias properties like center_x, right, top, etc. Setting them in kv doesn't automatically bind to the size of the widget (adding that to kivy is not as trivial as it sounds), so while the image is positionned correctly at first, if it's resized after, then the position is not updated, because the parent's pos didn't change, only the children's size! As luck would have it, in such situation, it's not uncommon to have code that seems to work half of the time, depending on the timing of dispatching in that particular run.
Anyway, the solution is quite simple, explicitly reference the children's size in the bindings, so the expression is recomputed every time it changes.
center_x: self.width and self.parent.center_x
center_y: self.height and self.parent.center_y

Related

ECharts disable symbol (marker) animation only

Take a look at this simple demo project I grabbed from their site:
https://ecomfe.github.io/echarts-examples/public/editor.html?c=dynamic-data2
Only thing I changed is the value of showSymbol. From false to true. So you can see the little dots on the line and how they slowly grow until they reach their final size. Since I can't save my own version of this demo you'll have to do so aswell to see what I mean.
There is a property called animation for series. This will in fact disable the grow animation, but will also disable all other animations connected with this series. For example the smooth transition to the left when new datapoints are added.
I don't want to hide the markers. I want them there, but without that animation.
Does anyone know of a way to achive this?
series: [{
name: '模拟数据',
type: 'line',
showSymbol: true,
hoverAnimation: false,
data: data,
animation: false
}],
animation: true
This can help disable the item animation while keeping animation of the X axis. But I'm afraid there's nothing more we can do with the line animation.

Qml Item grabToImage save image error

I'm using the
Item.grabToImage()
But I'm getting the following error.
QML ItemX: grabToImage: item has invalid dimensions
This is because I'm using height and width properties like so:
width: {
// return with * 0.4; based for some condition
// for eg
return parent.width * 0.4;
}
// and something similar with height
The only time that I can get the following code working is when I put in a static heigth and width:
grabToImage(
function(result)
{
result.saveToFile("/path/project-name/tmp/something.png");
}
);
Any ideas of why and how do I get around this problem?
Thank you
I'm not a 100% sure why, But it was something about the dynamic width of the parent.
In the program I wrote I has set the anchors of the image to the left and right of the preview container.
So when I tried to get the image capture from another item that was overlaying the image to cut out smaller parts of the image it was not letting me.
How I fixed this was to set a fixed image size of the source image and then just anchor it to the center of the preview section.
The only thing is now it will not size up if you scale the window.
I'm sure I could implement and on size change to the main program window and then set the width of the image (Not tested).
Last thing I should mention is that if the image is small then the cut out images from sections of the source image will be blurry and not good quality.
I fixed this by setting the "sourceSize.width" to a very large image and then used the "scale" property to scale down the image to fit within the preview item.

tvOS: Rounded corners for image view when focused

I have an image view that will get this awesome tvOS focus effect when the containing view gets focused.
The problem is - it should have rounded corners. Now this is easily done:
imageView.layer.cornerRadius = 5
imageView.layer.masksToBounds = true
I have to set either masksToBounds of the layer or clipsToBounds of the image view to true (which is basically the same), in order to clip the edges of the image - but as soon as I do this, the focus effect won't work any more, because it will get clipped as well.
I had more or less the same problem with buttons, but since the focus effect is much simpler than for the image view (only scaling and shadow), I just implemented it myself, but that is not an option for the image view, with all the effects applied (moving, shimmering, and so on...)
Is there an easier way? Did I miss something? I can't be the only trying to figure out how this works!? :)
I have found out an alternative solution. What one may do is to actually draw the image, clipping out the corners with an alpha channel. The image then gets scaled correctly when focused. That applied to the layer. Then, to have the alpha channel added to the other layers (like the one for the glowing effect) we need to set; "masksFocusEffectToContents = true".
I made an extension for it, based on this answer:
Swift 4.2
extension UIImageView {
func roundedImage(corners: UIRectCorner, radius: CGFloat) {
let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.frame.size)
UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 1)
UIBezierPath(
roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius)
).addClip()
self.draw(rect)
self.image = UIGraphicsGetImageFromCurrentImageContext()!
// Shadows - Change shadowOpacity to value > 0 to enable the shadows
self.layer.shadowOpacity = 0
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 10, height: 15)
self.layer.shadowRadius = 3
// This propagate the transparency to the the overlay layers,
// like the one for the glowing effect.
self.masksFocusEffectToContents = true
}
}
Then to apply the rounded corners call:
myImageView.adjustsImageWhenAncestorFocused = true
myImageView.clipToBounds = false
// masks all corners with a radius of 25 in myImageView
myImageView.roundedImage(corners: UIRectCorner.allCorners, radius: 25)
One can obviously modify roundedImage() to add the parameters to define the shadows at the calling time.
Downsides:
Borders behave like cornerRadius (they get drawn inside the image).
But I think I made it working somewhere, then investigating further I
lost the changes
I am not exactly sure this is the right way to do it. I am quite confident there must be some methods out there doing it in a couple of lines. In tvOS 11 Apple introduced the round badges (animatable and all), shown at WWDC 2017. I just can't find a sample for them.
Otherwise, tvOS 12 (beta for now) introduced the Lockup. I managed to implement them programmatically, as shown in this answer.
https://forums.developer.apple.com/thread/20513
We are also facing this same issue. When you round the corners, you can see the "shine" still has a rectange shape.
I showed the issue to the Dev Evangelists at the Tech Talks in Toronto and they said it's a bug. It's reported and open rdar://23846376
For 2022.
Note that you can just use UICardView on tvOS for the effect.
Simply put the UIImageView inside the card view.
Don't forget to actually turn OFF "adjust on ancestor focus" and "user interaction enabled" on the image view, or else it will "doubly expand" when the card view expands!
There's also a weird issue where you have to add 20 to the height of all card views to make them work neatly with and enclosed image view.

How to set widget depth in Kivy?

I'm designing a simple Kivy-based app that has an image in a Scatter widget and two buttons at a fixed position on the screen.
depthproblem.kv:
FloatLayout:
Scatter:
Image:
source: "img.png"
Button:
text: "Alpha"
pos_hint: {"x":0.00, "y":0}
size_hint: 0.20, 0.15
Button:
text: "Beta"
pos_hint: {"x":0.20, "y":0}
size_hint: 0.20, 0.15
depthproblem.py:
from kivy.app import App
class DepthProblemApp(App):
pass
DepthProblemApp().run()
The program starts with the buttons on top of the image, which is what I intend. This is because the buttons are declared after the scatter.
But when I touch the image, it lifts the image layer above the buttons. I don't understand why this happens, and couldn't find any documentation about how to control this behavior (searched z-index, order, layer, depth, etc.).
How can I specify the buttons to always be painted on top of the scatter/image?
Your problem with the scatter image coming to the front can be fixed by setting auto_bring_to_front to False. It defaults to True which is why you're getting that behavior.
Normally, the z-index (depth order) can be controlled by the order in which the widgets are added. The last one added, is displayed at the top I believe. See index of add_widget.

Unable to dynamically resize NSImageView

I have an NSImageView that encloses a dynamically generated NSImage. When I change the image displayed, I would like to dynamically resize the NSImageView so that it precisely wraps the new image, and also have the enclosing window resize so that the space between the NSImageView and every other part of the window remains constant. (Note that the image view's scaling is set to none, as I want its image to always be shown at its physical size.) To illustrate, suppose I begin with a small image in my image view. If I replace it with a large image, I wish for both the NSImageView and enclosing window to resize to accommodate it, without affecting the sizing or spacing of any other element.
Currently, I call the following method whenever the magnification level is changed via the stepper or associated text field. Though regenerating the image and loading it into the NSImageView works fine, resizing the NSImageView and enclosing window do not.
- (void) updateMagnification:(NSUInteger)newMagnification {
// Keep values of stepper and associated text field synchronized.
[self.magnificationStepper setIntegerValue:newMagnification];
[self.magnificationTextField setIntegerValue:newMagnification];
// Regenerate image based on newMagnification and display in image view.
[self.qrGenerator generateWithBlockPixelWidth:newMagnification];
self.imageView.image = self.qrGenerator.image;
// Adjust frame size of image view.
NSLog(#"Old size: frame=%# image=%#", NSStringFromSize(self.imageView.frame.size), NSStringFromSize(self.imageView.image.size));
[self.imageView setFrameSize:NSMakeSize(self.imageView.image.size.width, self.imageView.image.size.height )];
NSLog(#"New size: frame=%# image=%#", NSStringFromSize(self.imageView.frame.size), NSStringFromSize(self.imageView.frame.size));
//[self.window setViewsNeedDisplay:YES];
//[self.imageView setNeedsDisplay:YES];
//[self.imageView.superview setNeedsDisplay:YES];
}
Regardless of whether I increase or decrease the magnification value, causing the image to grow smaller or larger, the size of both the NSImageView and window remains constant. The three setNeedsDisplay: calls that are commented out have no effect even if they're uncommented -- they were my attempt to determine if the problem was related to the controls not redrawing once their size was adjusted, but the calls had no effect. Curiously, my NSLog calls indicate that the imageView's frame does indeed take the requested size, for they yield this output:
2012-06-12 11:02:50.651 Presenter[4660:603] Old size: frame={422, 351} image={168, 168}
2012-06-12 11:02:50.651 Presenter[4660:603] New size: frame={168, 168} image={168, 168}
The actual display, of course, does not change.
Interestingly, changing the imageView's frame style to "none," either in Interface Builder or programatically with [self.imageView setImageFrameStyle:NSImageFrameNone], gives me behaviour closer to what I desire. Making the image larger so that it would otherwise be clipped by the image view does indeed result in the image view and window growing larger. From this point, however, making the image smaller does not result in the image view or window resizing accordingly. "None" is the only image frame style that displays this somewhat correct behaviour -- all four of the bordered styles (i.e., bevel [which is the default], button, groove, and photo) show the same entirely incorrect behaviour described above.
I came across someone with a similar problem. Oddly, he only observed the problematic behaviour when his image view's frame style was set to NSImageFrameNone, when this is the only value that gives me somewhat-correct behaviour. I tried modifying the frame style to a non-none value before the resize and to none afterward, as this resolved the other person's problem, but for me, this yielded the same behaviour as when I simply set the frame style to "none" initially.
Any help you provide will be much appreciated. Thanks!

Resources