Kivy FileChooserListView - Modifying the display of the file list? - python-3.x

I was wondering if anyone knew how to add numbers (purely for reference) to Kivy's FileChooserListView such that the file list is displayed like:
# Name Size
1. File 1 2k
2. File 2 2k
3. File 3 2k
...

OK, it's not a perfect answer but here's what I tried to do:
First thing was to edit kivy's default filechooser.py file. Find this section:
ctx = {'name': basename(fn),
'get_nice_size': get_nice_size,
'path': fn,
'controller': wself,
'isdir': self.file_system.is_dir(fn),
'parent': parent,
'sep': sep}
and change it to:
ctx = {'name': basename(fn),
'get_nice_size': get_nice_size,
'path': fn,
'controller': wself,
'isdir': self.file_system.is_dir(fn),
'parent': parent,
'sep': sep,
'index': index}
Next up, find kivy's style.kv file (you could probably create a custom class to do this but I was being lazy!). Look for this section [FileListEntry#FloatLayout+TreeViewNode]:
I then took this part:
Label:
id: filename
text_size: self.width, None
halign: 'left'
shorten: True
text: ctx.name
and changed it to:
Label:
id: filename
text_size: self.width, None
halign: 'left'
shorten: True
text: "{}. {}".format(ctx.index, ctx.name)
As per my comment above, it seems to throw an error if you try to navigate folders.
It may be the case that one of the kivy experts knows a better way of doing this.

I know this is quite late but to complete the answer of elParaguayo, you also have to replace the lines
pardir = self._create_entry_widget(dict(
name=back, size='', path=new_path, controller=ref(self),
isdir=True, parent=None, sep=sep,
get_nice_size=lambda: ''))
with
pardir = self._create_entry_widget(dict(
name=back, size='', path=new_path, controller=ref(self),
isdir=True, parent=None, sep=sep,
get_nice_size=lambda: '', index= 0))
(be careful there are 2 occurences of these lines). This is what throws the exception when you navigate: the parent directory ../ is not created with the same lines as the other files.
Also, I would advise to create a local copy of filechooser.py and style.kv and load them into your app instead of modifying the source code of the kivy modules.

Related

How to modify current ScreenManager to another

Good afternoon.
I have a code structure with two ScreenManager:
id: sm ==> besides being my root it has only two screens
LoginScreen:
name: 'screen_login'
MainScreen:
name: 'main'
When the login is performed it directs me to the main screen:
On the screen named 'main' it has:
1 - MDToolbar
1 - MDNavigationLayout and it has a ScreenManager of
id: screen_manager with the following screens:
ScreenRecycleView
LoginScreen
ScreenSingUp
ScreenItem
1 - MDNavigationDrawer and it has a ContentNavigationDrawer with a creen_manager variable that inherits from the one described above.
There it is working beautifully!
I call any of the screens above and everything runs.
The problem is that I have a screen called
<ScreenRecycleView>:
name: 'recycle_view'
and this one has a MyImageCard class that has a button:
MDFlatButton:
text: "New Screen Here"
increment_width: "164dp"
On it I click and I can't call the screen that I pointed out in the example.
on_release:
app.root.screen_manager.current = 'screen_item'
I've tried everything I know, I'm for your help.
Below is my code reduced to the max to help them help me:
My code here.
I know my problem is screen manager but I can't solve it!
With your help I was able to discover:
app.root.get_screen('main').ids.screen_manager.current = 'screen_item'

How can I draw a tree with TikZ using PyLatex?

I have a homework assignment where I need to generate a PDF file containing a tree image using Python 3 and LaTeX's tikz package. It'd be really helpful if someone has a simple sample code.
I need to know how to create a child node.
from pylatex import (Document, TikZ, TikZNode, TikZDraw,TikZCoordinate,TikZUserPath, TikZOptions)
doc = Document()
# add our sample drawings
with doc.create(TikZ()) as pic:
node_kwargs = {'align': 'center', 'shape' : 'circle','minimum size': '50pt', 'fill': 'black!20'}
# create our test node
box = TikZNode(text='My block',
handle='box',
options=TikZOptions('draw',
'rounded corners',
**node_kwargs))
n_kw = {'shape' : 'circle',
'minimum size': '50pt',
'fill': 'black!20'}
#I DONT KNOW HOW TO PUT A CHILD NODE !!
box.child = TikZNode(text='My block 2',
handle='box2',
options=TikZOptions('draw',
'rounded corners',
**node_kwargs))
pic.append(box)
pic.append(box.child)
doc.generate_pdf('tikzdraw', clean_tex=False)

Get dictionary value from a List inside a dictionary

I am looking to get the value of the description field inside the weather.
{'coord': {'lon': 73.85, 'lat': 18.52}, 'weather': [{'id': 800, 'main': 'Clear', 'description': 'clear sky', 'icon': '01d'}], 'base': 'stations', 'main': {'temp': 305.381, 'pressure': 949.7, 'humidity': 31, 'temp_min': 305.381, 'temp_max': 305.381, 'sea_level': 1023.73, 'grnd_level': 949.7}
i have seen many posts and i am trying to do the below:
r1 = requests.get('http://api.openweathermap.org/data/2.5/weather?q=Pune,in&APPID=5ad6ec2537bfb0d574363e115c2d0041')
print(r1.status_code)
json_data = json.loads(r1.text)
print(json_data)
print("Weather is" ,json_data["weather"][0])
But the above is fetching me all the values inside the dictionary.
What's the best way to achieve that?
Thanks.
Use json_data["weather"][0]['description'] to access the description field.

kivy: badly aligned widgets

Example code fragment from a base class:
def build_extra_content(self):
grp = 'choice_dialog'
extra_content = GridLayout(cols=2)
lb_width = self.width - 2 * self.choice_height
for choice in self.choices:
cb = CheckBox(group=grp,
size_hint=(None, None), size=(self.choice_height, self.choice_height))
lb = Label(markup=True, text=choice, halign='left', valign='middle',
size_hint=(None, None), size=(lb_width, self.choice_height))
lb.texture_size = (lb_width, self.choice_height)
extra_content.add_widget(cb)
extra_content.add_widget(lb)
# TODO: check the checkbox when the label is touched.
def _lb_press(*args):
print(args)
cb.bind(on_touch_down=_lb_press)
return extra_content
The content is displayed in this dialog:
I have two questions. First: why the text is aligned to the center? I have already set absolute sizes for both the label and its texture size, and set halign='left'. But the text is still aligned to the center. Why?
Second: I wanted the labels to be clickable/touchable. E.g. the checkboxes should be selected by touching their corresponding labels. Whenever I click on a single label or checkbox, this is printed:
(<kivy.uix.checkbox.CheckBox object at 0x0B2C01B8>, <MouseMotionEvent button="left" device="mouse" double_tap_time="0" dpos="(0.0, 0.0)" dsx="0.0" dsy="0.0" dsz="0.0" dx="0.0" dy="0.0" dz="0.0" grab_current="None" grab_exclusive_class="None" grab_list="[]" grab_state="False" id="mouse3" is_double_tap="False" is_mouse_scrolling="False" is_touch="True" is_triple_tap="False" opos="(644.0, 379.0)" osx="0.503125" osy="0.47375" osz="0.0" ox="644.0" oy="379.0" oz="0.0" pos="(644.0, 379.0)" ppos="(644.0, 379.0)" profile="['pos', 'button']" psx="0.503125" psy="0.47375" psz="0.0" push_attrs="('x', 'y', 'z', 'dx', 'dy', 'dz', 'ox', 'oy', 'oz', 'px', 'py', 'pz', 'pos')" push_attrs_stack="[]" px="644.0" py="379.0" pz="0.0" shape="None" spos="(0.503125, 0.47375)" sx="0.503125" sy="0.47375" sz="0.0" time_end="-1" time_start="1507722998.229789" time_update="1507722998.229789" triple_tap_time="0" ud="{}" uid="3" x="644.0" y="379.0" z="0.0">)
(<kivy.uix.checkbox.CheckBox object at 0x0B5FC2D0>, <MouseMotionEvent button="left" device="mouse" double_tap_time="0" dpos="(0.0, 0.0)" dsx="0.0" dsy="0.0" dsz="0.0" dx="0.0" dy="0.0" dz="0.0" grab_current="None" grab_exclusive_class="None" grab_list="[]" grab_state="False" id="mouse3" is_double_tap="False" is_mouse_scrolling="False" is_touch="True" is_triple_tap="False" opos="(644.0, 379.0)" osx="0.503125" osy="0.47375" osz="0.0" ox="644.0" oy="379.0" oz="0.0" pos="(644.0, 379.0)" ppos="(644.0, 379.0)" profile="['pos', 'button']" psx="0.503125" psy="0.47375" psz="0.0" push_attrs="('x', 'y', 'z', 'dx', 'dy', 'dz', 'ox', 'oy', 'oz', 'px', 'py', 'pz', 'pos')" push_attrs_stack="[]" px="644.0" py="379.0" pz="0.0" shape="None" spos="(0.503125, 0.47375)" sx="0.503125" sy="0.47375" sz="0.0" time_end="-1" time_start="1507722998.229789" time_update="1507722998.229789" triple_tap_time="0" ud="{}" uid="3" x="644.0" y="379.0" z="0.0">)
(<kivy.uix.checkbox.CheckBox object at 0x0B5F3768>, <MouseMotionEvent button="left" device="mouse" double_tap_time="0" dpos="(0.0, 0.0)" dsx="0.0" dsy="0.0" dsz="0.0" dx="0.0" dy="0.0" dz="0.0" grab_current="None" grab_exclusive_class="None" grab_list="[]" grab_state="False" id="mouse3" is_double_tap="False" is_mouse_scrolling="False" is_touch="True" is_triple_tap="False" opos="(644.0, 379.0)" osx="0.503125" osy="0.47375" osz="0.0" ox="644.0" oy="379.0" oz="0.0" pos="(644.0, 379.0)" ppos="(644.0, 379.0)" profile="['pos', 'button']" psx="0.503125" psy="0.47375" psz="0.0" push_attrs="('x', 'y', 'z', 'dx', 'dy', 'dz', 'ox', 'oy', 'oz', 'px', 'py', 'pz', 'pos')" push_attrs_stack="[]" px="644.0" py="379.0" pz="0.0" shape="None" spos="(0.503125, 0.47375)" sx="0.503125" sy="0.47375" sz="0.0" time_end="-1" time_start="1507722998.229789" time_update="1507722998.229789" triple_tap_time="0" ud="{}" uid="3" x="644.0" y="379.0" z="0.0">)
Actually it doesn't matter where I click. Even if I click outside the GridLayout, always all labels will trigger the touch event. But why? I only want the one under my finger.
Thanks
First: why the text is aligned to the center? I
have already set absolute sizes for both the label and its texture
size, and set halign='left'. But the text is still aligned to the
center. Why?
You're setting texture_size, but you should set text_size instead.
Second: I wanted the labels to be clickable/touchable. E.g. the
checkboxes should be selected by touching their corresponding labels.
Whenever I click on a single label or checkbox, this is printed:
In Kivy every widget receive touch event. You should check if touch happened inside your label manually:
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
# The touch has occurred inside the widgets area. Do stuff!
pass
Here is the answer to your second question.
Note
By default, touch events are dispatched to all currently displayed
widgets. This means widgets receive the touch event whether it occurs
within their physical area or not.
In order to provide the maximum flexibility, Kivy dispatches the
events to all the widgets and lets them decide how to react to them.
If you only want to respond to touch events inside the widget, you
simply check:
Example
class ProjectSelectButton(Button):
def click_on_button(self, instance, touch, *args):
print(instance)
if self.collide_point(*touch.pos):
if touch.button == 'right':
print(self.id, "right mouse clicked")
elif touch.buttom == 'left':
print(self.id, "left mouse clicked")
return True
return super(ProjectSelectButton, self).on_touch_down(touch)

Python flickrapi search.photos returns the same picture on every page

I'm testing the flickrapi for python and have some code that randomly chooses a picture of Chinese food. It does this by getting 1 result on 1 page and using the total number of pages in that result to choose 1 result on 1 random page. Here is the code I'm using to get the images:
flickr = flickrapi.FlickrAPI(api_key='mykey', secret='mysecret', format='parsed-json', cache=False)
data1 = flickr.photos.search(tags='Chinese Food',
page=1,
per_page=1,
tag_mode='all',
media='photos',
content_type=1)
data2 = flickr.photos.search(tags='Chinese Food',
page=randint(1, data1['photos']['pages']),
per_page=1,
tag_mode='all',
media='photos',
content_type=1,
extras='url_l')
No matter what I do the result in data2 is always the exact same image returned in data1, I could get the first result from page 1 and the first result from page 3472 and the image is exactly the same every time.
Here is a sample of the data returned
//From data1
{'photos': {'page': 1, 'pages': 70007, 'perpage': 1, 'total': '70007', 'photo': [{'id': '35800805325', 'owner': '24171591#N06', 'secret': '408928a034', 'server': '4261', 'farm': 5, 'title': 'Personalized Maple Wood Chopsticks', 'ispublic': 1, 'isfriend': 0, 'isfamily': 0}]}, 'stat': 'ok'}
//From data2
{'photos': {'page': 41043, 'pages': 70007, 'perpage': 1, 'total': '70007', 'photo': [{'id': '35800805325', 'owner': '24171591#N06', 'secret': '408928a034', 'server': '4261', 'farm': 5, 'title': 'Personalized Maple Wood Chopsticks', 'ispublic': 1, 'isfriend': 0, 'isfamily': 0, 'url_l': 'https://farm5.staticflickr.com/4261/35800805325_408928a034_b.jpg', 'height_l': '859', 'width_l': '1024'}]}, 'stat': 'ok'}
Notice the id and title in both sets of data are exactly the same and the page numbers are different. I've tested this in the Flickr API explorer with the exact same parameters and I do get the same image when I specify page 1 but I also get a completely different image if I specify any other page, so this seems to be an issue with the python flickrapi implementation or one of its dependencies maybe?
I can't seem to find the issue. What is going on?
Looks like other people have been having this issue with Flickr's API since 2011 and it still hasn't been fixed. So, it doesn't seem to be related to Python or the Python Flickr module. I was able to improve the "randomness" by increasing the number of results per page which is something I didn't want to do but it's the only thing that works.

Resources