#python-3.x #kivy #kivymd
Вопрос:
в настоящее время я пытаюсь создать интерфейс youtube, который фильтрует алгоритм youtube, чтобы вы не тратили свое время на развлечения, и я столкнулся с проблемой, которую я не знаю, как решить из-за недостатка знаний
Проблема: аргумент в функции для on_release в элементе списка одинаков для всех элементов списка (т. е. аргумент функции on_release последнего элемента списка каким-то образом используется для всех элементов списка)
Я выбираю канал 1 (лучшие идеи)
изображение 1
Я получаю «Канал изучения японского языка» вместо «лучшие идеи» изображение канала
2
важно получить правильное название канала, так как тогда я смогу удалить видеоинформацию этого канала
код, который я использовал для добавления элементов в список каналов:
def on_start(self):
channel_logos_dir = "static/channel_images/"
channel_logos_list = os.listdir(channel_logos_dir)
for channel_logo_name in channel_logos_list:
channel_name = channel_logo_name[:-4]
print(channel_name)
image = ImageLeftWidget(source=channel_logos_dir channel_logo_name)
item = TwoLineAvatarListItem(text=channel_name, on_release=lambda x: self.chan_page(channel_name))
item.add_widget(image)
self.root.ids.subs_scr_id.ids.subs_id.add_widget(item)
иерархия папок для изображений:
static
|-- channel_images
|-- Better Ideas.jpg
|-- Krish Naik.jpg
|-- Learn Japanese with JapanesePod101.com.jpg
Здесь название канала для всех элементов в списке-это название канала последнего элемента
on_release=lambda x: self.chan_page(channel_name)
Весь мой код:
import os
from kivymd.app import MDApp
from kivymd.uix.screen import Screen
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager
from kivymd.uix.list import TwoLineAvatarListItem, ImageLeftWidget
from kivymd.uix.floatlayout import MDFloatLayout
from kivymd.uix.tab import MDTabsBase
Window.size = (300, 500)
channels = {"Krish Naik":"https://www.youtube.com/user/krishnaik06",
"Learn Japanese with JapanesePod101.com":"https://www.youtube.com/c/japanesepod101",
"Better Ideas":"https://www.youtube.com/c/BetterIdeas/"}
screen_helper = """
ScreenManager:
HomeScreen:
id: home_src_id
SubscriptionScreen:
id: subs_scr_id
ChannelScreen:
id: channel_scr_id
<HomeScreen>:
name: 'home'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'YouTube'
left_action_items: [["youtube", lambda x: app.navigation_draw()]]
right_action_items: [["magnify", lambda x: app.search_popup()]]
MDIconButton:
icon: "youtube-subscription"
md_bg_color: app.theme_cls.primary_color
pos_hint: {'center_x':0.5, 'center_y':0.5}
on_press: root.manager.current = "subscriptions"
MDLabel:
text: 'Go to subscriptions using top menu'
halign: 'center'
MDRectangleFlatButton:
text:'profile'
pos_hint: {'center_x':0.5, 'center_y':0.5}
on_press: root.manager.current = "subscriptions"
<SubscriptionScreen>:
name: 'subscriptions'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'YouTube'
left_action_items: [["youtube", lambda x: app.navigation_draw()]]
right_action_items: [["magnify", lambda x: app.search_popup()]]
MDIconButton:
icon: "youtube-subscription"
md_bg_color: app.theme_cls.primary_color
pos_hint: {'center_x':0.5, 'center_y':0.5}
on_press: root.manager.current = "profile"
ScrollView:
MDList:
id: subs_id
<ChannelScreen>
name: 'channelPage'
MDBoxLayout:
orientation: "vertical"
MDToolbar:
id: channel_name
left_action_items: [["keyboard-backspace", lambda x: app.navigation_draw()]]
right_action_items: [["dots-vertical", lambda x: app.search_popup()]]
MDTabs:
id: tabs
on_tab_switch: app.on_tab_switch(*args)
<Tab>
ScrollView:
MDList:
id: vids_id
"""
class HomeScreen(Screen):
pass
class SubscriptionScreen(Screen):
pass
class ChannelScreen(Screen):
pass
class Tab(MDFloatLayout, MDTabsBase):
'''Class implementing content for a tab.'''
sm = ScreenManager()
sm.add_widget(HomeScreen(name='home'))
subscription_screen = SubscriptionScreen(name='subscriptions')
sm.add_widget(subscription_screen)
sm.add_widget(ChannelScreen(name='channelPage'))
sm.current = "home"
class DemoApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.current_channel = 'Krish Naik'
def build(self):
self.theme_cls.primary_palette = 'Red'
screen = Builder.load_string(screen_helper)
return screen
def on_start(self):
channel_logos_dir = "static/channel_images/"
channel_logos_list = os.listdir(channel_logos_dir)
for channel_logo_name in channel_logos_list:
channel_name = channel_logo_name[:-4]
image = ImageLeftWidget(source=channel_logos_dir channel_logo_name)
item = TwoLineAvatarListItem(text=channel_name, on_release=lambda x: self.chan_page(channel_name))
item.add_widget(image)
self.root.ids.subs_scr_id.ids.subs_id.add_widget(item)
self.root.ids.channel_scr_id.ids.tabs.add_widget(Tab(title=f"Videos"))
self.root.ids.channel_scr_id.ids.tabs.add_widget(Tab(title=f"Playlists"))
self.root.ids.channel_scr_id.ids.tabs.add_widget(Tab(title=f"Community"))
def on_tab_switch(
self, instance_tabs, instance_tab, instance_tab_label, tab_text
):
'''Called when switching tabs.
:type instance_tabs: <kivymd.uix.tab.MDTabs object>;
:param instance_tab: <__main__.Tab object>;
:param instance_tab_label: <kivymd.uix.tab.MDTabsLabel object>;
:param tab_text: text or name icon of tab;
'''
for i in range(20):
image = ImageLeftWidget(source="static/channel_images/Krish Naik.jpg")
item = TwoLineAvatarListItem(text="krish naik", on_release=lambda x: self.chan_page(channel_name))
item.add_widget(image)
instance_tab.ids.vids_id.add_widget(item)
# @staticmethod
def chan_page(self,channel_name):
self.root.current = "channelPage"
self.root.ids.channel_scr_id.ids.channel_name.title = channel_name
self.current_channel = channel_name
DemoApp().run()
Мой вывод:
C:UsersrahimPycharmProjectsyt_filtervenvScriptspython.exe C:/Users/rahim/PycharmProjects/yt_filter/mian.py
[INFO ] [Logger ] Record log in C:Usersrahim.kivylogskivy_21-07-01_91.txt
[INFO ] [deps ] Successfully imported "kivy_deps.gstreamer" 0.3.2
[INFO ] [deps ] Successfully imported "kivy_deps.angle" 0.3.0
[INFO ] [deps ] Successfully imported "kivy_deps.glew" 0.3.0
[INFO ] [deps ] Successfully imported "kivy_deps.sdl2" 0.3.1
[INFO ] [Kivy ] v2.0.0
[INFO ] [Kivy ] Installed at "C:UsersrahimPycharmProjectsyt_filtervenvlibsite-packageskivy__init__.py"
[INFO ] [Python ] v3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)]
[INFO ] [Python ] Interpreter at "C:UsersrahimPycharmProjectsyt_filtervenvScriptspython.exe"
[INFO ] [KivyMD ] 0.104.2, git-bc7d1f5, 2021-06-06 (installed at "C:UsersrahimPycharmProjectsyt_filtervenvlibsite-packageskivymd__init__.py")
[INFO ] [Factory ] 186 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL" graphics system
[INFO ] [GL ] GLEW initialization succeeded
[INFO ] [GL ] Backend used <glew>
[INFO ] [GL ] OpenGL version <b'4.6.13596 Compatibility Profile Context 20.10.35.02 27.20.1034.6'>
[INFO ] [GL ] OpenGL vendor <b'ATI Technologies Inc.'>
[INFO ] [GL ] OpenGL renderer <b'AMD Radeon(TM) Vega 8 Graphics'>
[INFO ] [GL ] OpenGL parsed version: 4, 6
[INFO ] [GL ] Shading version <b'4.60'>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <32>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [GL ] NPOT texture support is available
[INFO ] [Base ] Start application main loop
[INFO ] [Loader ] using a thread pool of 2 workers
[WARNING] Deprecated property "<StringProperty name=text>" of object "<__main__.Tab object at 0x000002D50A02F120>" has been set, it will be removed in a future version
[INFO ] [Base ] Leaving application in progress...
Process finished with exit code 0
Спасибо, что уделили мне время
Ответ №1:
Это распространенная ошибка при использовании lambda
внутри цикла. lambda
Функция ссылается на переменную, область действия которой находится в цикле, и когда lambda
она выполняется, эта переменная имеет последнее значение, которое ей было присвоено в цикле. Исправление заключается в создании нового аргумента lambda
функции, например:
item = TwoLineAvatarListItem(text=channel_name, on_release=lambda x, y=channel_name: self.chan_page(y))