How to create the duplicate widget? - python

I'm trying create new TabbedPanelItem with properties already created widget. But i'm getting new empty widget or replace exist.
.py
class MainScreen(Screen):
def add(self, tabbed_item):
new_tabbed_item = TabbedPanelItem()
new_tabbed_item.properties = copy(tabbed_item)
new_tabbed_item.text = "2"
self.ids.tab_panel.add_widget(new_tabbed_item)
.kv
<MainScreen>:
AnchorLayout:
canvas.before:
...
TabbedPanel:
id: tab_panel
...
TabbedPanelItem:
Button:
on_press: root.add(tab_item)
TabbedPanelItem:
id: tab_item
....

When I try to run you're code nothing pops up. You don't have enough code to test. I'm not sure what your goal is, but if you want to have a TabbedPanelItem with stuff already created without having to reproduce the same code (if that's your goal), try using #. An example: MyTabbedPanel#TabbedPanelItem:. Then you can add everything you want it to do, and reuse it instead of retyping out the code everytime.

Related

How to collect data from python-file to kv-file

I want to create a Label in my kv-file and the text I want the Label to have is supposed to be collected from my python-file. I have tried to create a function in the python-file that has a variable equal to the string I want the Label to have, but it does not seem to work and I don't know how to do it correctly...
The code below is how my kv-file looks. So it is in the field that says "text:" that I want to collect the data from my python-file.
Hope someone knows how to do!
<FirstScreen>:
GridLayout:
cols: 2
text:
In your class FirstScreen you can add a StringProperty to represent the text.
class FirstScreen(Screen):
mytext = StringProperty('default text')
Then, in your kv you can use it as:
<FirstScreen>:
Label:
text: root.mytext

Multiple actions on release in Kivy

Can I just put more function in this on release or this wont work. I want to have more pop functions and pictures displayed, maybe some audio, etc. This is .kv file:
<Root>:
orientation: 'vertical'
RecordButton:
id: record_button
background_color: 1,1.01,0.90,1
text: 'Order'
on_release:
self.record()
root.pop1()
height: '100dp'
size_hint_y: None
TextInput:
text: record_button.output
readonly: True
Defining an event callback as sequence of statements.
Inside the KV file
Indentation and thus structuring control-flow readable is limited in a KV file. As inclement commented there are basically 2 ways for defining a callback sequence:
statements per line (same indentation)
semicolon separated statements
on_release:
self.record()
root.pop1()
on_press: print('pressed'); self.insert_text("pressed!")
See Kivy-language syntax Valid expressions inside :
[..] multiple single line statements are valid, including those that escape their newline, as long as they don’t add an indentation level.
Define a function in Python
You have more flexibility to define the a function inside the Python script and declare this callback on the event inside the KV file.
For example the function as method of your RecordButton (assume its a class extending Button) in Python:
class RecordButton(Button):
# callback function tells when button released
# It tells the state and instance of button.
def record_and_pop(self, instance):
print("Button is released")
print('The button <%s> state is <%s>' % (instance.text, instance.state))
self.record()
root.pop1()
then used inside the KV:
RecordButton:
on_release: self.record_and_more()
See also
kivy: firing multiple functions on 1 button click
Kivy API: Button class

Python Kivy library adding widgets

For example we created with kivy language simple BoxLayout1 that contains button1 and another BoxLayout2. When you click button1 it adds a new button in BoxLayout2 but it's written in python.
Is it possible to acces existing layout in kv language, in python code? Or only solution is writting whole window in python?
I couldn't find any info in kivy docs, maybe I've just missed something.
EDIT:
I've something like this
Kv:
<CreateWindow>:
BoxLayout:
Button:
text: "test"
on_release: root.press()
BoxLayout:
Label:
text: "Label"
Python:
class CreateWindow(Screen):
def press(self):
I want to add a new button near Label by activating press function
in python will be like this
class CreateWindow(Screen):
def press(self):
# the first box is the first child in the children list of the CreateWindow widget so
box1=self.children[0]
box2=self.children[1]
# and now you can decide which box you want to use add_widget method with
# in your case it should be
box2.add_widget(Button())

Why does this not load the ids of the contents in the BoxLayout? (Kivy)

Why does this code get a KeyError, from line #21?
I've tried different versions of similar code, but this is the only file that gets the KeyError.
Gist: https://gist.github.com/Crowbrammer/464ae3ae3ddd7d33a9eb64d856acacd0
Why is it missing the id's of each element in the Kivy file?
How come the function beneath the init() function works, with that exact same line of code--but the init() function doesn't?
I don't think record_new_model gets called.
Your constructor fails so the rest doesn't matter.
You aren't setting the ids properly.
You need to do something like this
<ModelAddLayout>:
model_add_name: model_add_name
orientation: 'vertical'
padding: 20, 20
Label:
id: title_label
text: 'Model Add Screen'
font_size: '30dp'
# text_size: '15dp'
TextInput:
id: model_add_name
text: 'Add your model name here'
multiline: False
When you are adding an id to a child it doesn't get added to the parent. You also need to add the id to the parent: model_add_name: model_add_name.
The root determines what elements get loaded into the code first.
For this code is ScreenManagement. The root for others is ModelAddLayout.
So, for the code I linked, it loads the elements of the kv file later than I expect, so there are no keys in the ids attribute to call.
What I did get to work, then, was to put everything except super() into a new function, late_init(self, keys, **largs).
After that, I put Clock.schedule_once(self.late_init, 0) after init()'s super.
This gave the app time to populate the ids, enabling my dropdown list to become a reality.
(From the comment to Radu Dita's answer.)

Is it necessary to add a `FloatLayout` inside a `Widget`?

If I have a class that I define in the Python source file as a child of Widget, is it necessary for me add a FloatLayout a child, or can I just position the elements inside the Widget directly, without using a FloatLayout at all?
# Python source
class FooBar(Widget):
pass
# Kivy source
<FooBar>:
FloatLayout: # Is this necessary?
SomeChildWidget:
...
AnotherChildWidget:
...
There is nothing wrong with embed widgets inside widgets. You are in complete control of the position and sizing.
The add_widget method (and children property) is part of the Widget class, and Layout just inherits from Widget. As an example, the Kivy pong tutorial doesn't have any layouts.
Note: If you are start wondering about the difference of using Widget and FloatLayout. Basically, the latter honours Widget.pos_hint and Widget.size_hint attributes. It allows you to use proportional values to the size of the Widget for positioning.
A quick look over the Kv language documentation suggests that no, you don't need a layout inside the widget. Consider the example they give under the template section:
<MyWidget>:
Button:
text: "Hello world, watch this text wrap inside the button"
text_size: self.size
font_size: '25sp'
markup: True
Button:
text: "Even absolute is relative to itself"
text_size: self.size
font_size: '25sp'
markup: True
Button:
text: "Repeating the same thing over and over in a comp = fail"
text_size: self.size
font_size: '25sp'
markup: True
Here 3 button widgets have been placed directly under the <MyWidget> declaration.

Categories

Resources