looking to set up a reusable button in my kivy file that includes various root.manager.get_screen instructions under on_press ... Anyone know if this is possible to do in the kv? Thanks so much for any help in advance
<ProductButton#Button>
color: 'black'
outline_color: 'white'
outline_width: 15
on_press:
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
root.manager.current = (root.ids.product1.text+root.ids.label.text+'Detail')
root.manager.get_screen(root.manager.MY_GLOBAL).ids.selection.background_normal = self.background_normal
etc.
The code works in the individual screens but it is long and ugly so I would like to set up a macro instead...
Here is the error I get -
AttributeError: 'ProductButton' object has no attribute 'manager'
Related
I'm new to kivy and I want to access the touch Object without overwriting motion event functions like on_touch_down(self,touch), on_touch_up(), etc..
I want to access touch.pos in order to dynamically draw lines on an Image in a Scatter Class.
Simplified my kv file looks like the following:
<Map#Scatter>:
source: None
do_rotation: False
Image:
id: main_image
source: root.parent.parent.parent.parent.map_path
allow_stretch: True
keep_ratio: True
size_hint_y: None
size_hint_x: None
width: self.parent.width
height: self.parent.width/self.image_ratio
<Zoom>:
id: zoom_class
Map:
id: map_class
<RoomMarkerScreen>:
id: room_marker_screen
AnchorLayout:
rows: 2
AnchorLayout:
anchor_x: 'center'
anchor_y: 'top'
Zoom:
id: zoom_class
AnchorLayout:
anchor_x:'center'
anchor_y: 'bottom'
Button:
text: "Fix/Unfix Map"
size_hint: 0.5, 0.05
on_press:
root.fix_unfix(root.fix)
Knowing that Class Zoom Inherits from FloatLayout, how can I access Touch Object in Zoom?
Thanks in advance!
If I take the touch.pos from the event motion functions, they will be overwritten and I won't be able use the drag and scale features that came with the Scatter Class.
Whenever you write a function that exists in a super class, you should call that that super class method, otherwise, you will be interfering in the functioning of that super class (for example, DragBehavior). So, I suggest trying something like:
class Zoom(FloatLayout):
fixed_map = BooleanProperty(False)
def on_touch_down(self, touch):
print(touch.pos)
return super(Zoom, self).on_touch_down(touch)
And returning True from a on_touch_down() method stops all further dispatching of that touch event, so other widgets do not see that event. See the documentation.
Also, from the same documentation:
on_touch_down(), on_touch_move(), on_touch_up() don’t do any sort of
collisions. If you want to know if the touch is inside your widget,
use collide_point().
(1) By using the following kv file version was able to place BorderImagewidget at the specified position..
<Screen>:
ProgressBar:
max: 100
pos_hint: {'top':0.86, 'x':0.01}
size_hint_x: 0.49
size_hint_y: 0.1
canvas:
BorderImage:
border: (10, 10, 10, 10)
pos: self.x, self.center_y
size: self.width, 8
source: '0.png'
(2) But, the following Pure Python code that should realize the same function as (1) doesn't work properly.BorderImagewidget is placed at the bottom of the screen.
pos_hint={'top':0.86,'x':0.01} doesn't work.
I think that how to specify pos=(bar.x, bar.center_y) is not good because bar.center_y value is different from the code of (1).
class BarWidget(FloatLayout):
def __init__(self, **kwargs):
super(BarWidget, self).__init__(**kwargs)
self.build()
def build(self):
bar = ProgressBar(pos_hint={'top':0.86,'x':0.01}, max=100, size_hint_x=0.49, size_hint_y=0.1)
with bar.canvas:
BorderImage(border=(10, 10, 10, 10), pos=(bar.x, bar.center_y), size=(self.width/2, 8), source='0.png')
self.add_widget(bar)
How should I modify bar.center_y?
(1):screen shot
(2):screen shot
In the kv language, when you set an attribute like size: self.size, this attribute is automatically updated whenever the 'self' widget changes size of shape. When things are loading up in a screen/layout, they start with funky positions and sizes then move to be correct. Since things automatically update upon changing sizes/positions if you work in kv, it works as you expect.
In python, you have to explicitly bind some function to update the canvas if the size or position of the widget it's inheriting its size and pos from changes. You can do that by using the bind function (available in most/all kivy widgets). Using bind, you can say bind(<attribute>=<function>) which means anytime the widget's <attribute>, aka size or pos, is changed, it calls the <function>
I didn't test this exactly with your code since not all of it is posted, but this is what I do for my projects. Let me know how it works. If it doesn't work, edit your answer to be a snippet of code that I can copy/paste to work with and I'll update my answer.
class BarWidget(FloatLayout):
def __init__(self, **kwargs):
super(BarWidget, self).__init__(**kwargs)
self.build()
def build(self):
# Make it so you can reference the bar and border image later
self.bar = ProgressBar(pos_hint={'top':0.86,'x':0.01}, max=100, size_hint_x=0.49, size_hint_y=0.1)
with self.bar.canvas:
# Make it so you can reference the border image
self.border_image = BorderImage(border=(10, 10, 10, 10), pos=(bar.x, bar.center_y), size=(self.width, 8), source='0.png')
self.add_widget(self.bar)
# Make it so whenever the widget's pos or size changes, we update the border image
self.bar.bind(pos=self.update_border_image, size=self.update_border_image)
# make a function to update border image
def update_border_image(self, *args):
self.border_image.size = (self.width, 8) # Should this 8 be 0.8 by the way?
self.border_image.pos = (self.bar.x, self.bar.center_y)
I am relatively new in Kivy. Having studied quite a bit on my laptop, everything works fine until i started working on my surface pro 4. All my buttons were placed in wrong positions, irrespective of how I specify the position, pos or pos_hint, eg:
the window
above is the window that appears when the following code is run:
<Button>:
color: .8, .9, 0, 1
font_size: 31
size_hint: .4, .3
<FloatLayout>
Button:
text: 'button1'
pos_hint: {'x':0, 'top': 1}
Button:
text: 'button2'
pos_hint: {'right': 1, 'y': 0}
could this be due to issues with OpenGL on surface pro 4 or could I have done something totally dumb?
After going through the documentation, I was able to locate the config.ini file on my c: drive and changed the rotation value from 90 to 0. rotation = 0 and my widgets are placed as expected. Kudos to the Kivy.org team, great documentation.
Already I have created a normal yAxis plotline with label styles.But now I want to create a yAxis plotline with some CSS styles. Any Suggestions?
This is what i have tried so far
This is my code
var chart = $('#tv_chart_container').highcharts();
chart.yAxis[0].removePlotLine('hori_line');
data = chart.series[0].data;
var test = data.length;
var value = data[999].y;
chart.yAxis[0].addPlotLine({
value: value, // Value of where the line will appear
width: 2 ,
color: '#248EC6',
// dashStyle: 'dash',
id: 'hori_line',
label: {
text: value,
align: 'right',
style: {
color: '#FFFFFF',
fontWeight: 'bold',
}
}
});
Here is the sample.What i actually need
I worked up a proof-of-concept that gets pretty close to what you're asking. This is using all code within Highcharts, and not anything dealing with outside CSS.
Plot lines can't possess the data label formatting you're seeking, so I used a scatter plot series to serve as the line instead. Plus, this also gives you the (default) Highcharts animation when you move over a new point in your line graph.
I did a few things here:
I added the scatter plot line as a separate "dummy" series that the user won't see in the legend and won't be able to interact with.
I formatted the data label for the last (second) point of the scatter plot line to show the blue background and white numerals as in your example.
I set a marker on the last (second) point of the scatter plot line with a diamond shape. Together with the data label settings, this gives you the marker example you showed above. Now, there is a shape: 'callout' option for data labels, but the carats only point up or down for this kind of series.
I updated your mouseOver event to update the value of the scatter plot line, rather than adding and removing plot lines.
Here's the proof-of-concept fiddle: http://jsfiddle.net/brightmatrix/tzu3khp1/. You can also see a screenshot of the result below.
I hope all of this information is helpful for you. Please let me know if you have any questions; I'll be glad to update this answer to elaborate.
In this example, we can see a rotation of the canvas. But clicking the button's corners isn't registered. How can I rotate the entire button?
You can probably override its collide_point method to account for the rotation by transforming the touch coordinates.
If you use the widget system (e.g. putting the Button in a Scatter), the collision is taken care of for you.
Based on inclement's answer, I've created a button on a scatter layout, which has its hitbox set correctly.
from kivy.app import App
from kivy.lang import Builder
kv = '''
FloatLayout:
ScatterLayout:
size_hint: None, None
size: 200, 200
pos_hint: {'center_x': .5, 'center_y': .5}
rotation: 45
do_rotation: False
do_scale: False
do_translation: False
Button:
text: 'hello world'
'''
class RotationApp(App):
def build(self):
return Builder.load_string(kv)
RotationApp().run()
I used scatter layout instead of scatter, because it passes its size to children widgets. The do_x: False aren't needed in this example, because button intercepts touching events, but if I placed a label, it would move on touch.