【问题标题】:Kivy button implementation - how can I do that with my written code?Kivy 按钮实现 - 我怎样才能用我的书面代码做到这一点?
【发布时间】:2018-11-13 15:21:12
【问题描述】:

我是 python 和 kivy 编程的新手,为了了解更多信息,我尝试制作一个小型音乐播放器 - 如果我从窗格旁边的 balk 列表中选择,它会播放声音 - 但我无法理解窗格本身可以工作 - 我需要一些解释如何实现这一点,而类似的主题并不是很有帮助。我试图让握把布局中的 4 个按钮正常工作 - 但没有任何效果。这是我在 python\kivy 中的代码:

import kivy
kivy.require('1.10.0')
from kivy.config import Config
Config.set('graphics', 'fullscreen', '0')

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from os import listdir, path

Builder.load_file("views/theme.kv")

class Player(Widget):
    directory = "" #directory path;
    currentlyplaying = "" #now playing song;

    def Gettrack_path(self):
        try:
            track = open("path/path.dat", "r")
            self.ids.direct.text = str(track.readline())
            track.close()
            self.ids.searchBtn.text = "Search"
            self.load_tracks()
        except:
           self.ids.direct.text = ''

    def Savetrack_path(self, path):
        track = open("path/path.dat", "w")
        track.write(path)
        track.close()

    def select(self, path):
        self.directory = path
        self.ids.direct.text - self.directory
        self.ids.searchBtn.text = "Search tracks"
        self.Savetrack_path(self.directory)
        self.load_tracks()

    def load_tracks(self):
        tracks = []
        self.directory = self.ids.direct.text
        if not self.directory.endswith("/"):
            self.directory += "/"

        if not path.exists(self.directory):
            self.ids.status.text = "Given path doesn't exist"
            self.ids.status.color = (1,0,0,1)
        else:
            self.ids.status.text = ""
            self.ids.scroll.bind(minimum_height = self.ids.scroll.setter("height"))

        for file in listdir(self.directory):
            if file.endswith(".mp3") or file.endswith(".wav") or file.endswith(".aiff") or file.endswith(".aac") or file.endswith(".ogg") or file.endswith(".mp4") or file.endswith(".wma"):
                tracks.append(file)
        if tracks == [] and self.directory != "":
            self.ids.status.text = "No tracks found"
            self.ids.status.color = (1,0,0,1)
        if self.directory == "/" or self.directory == "":
            try:
                self.ids.status.text = "No tracks found - given path doesn't exist"
                self.ids.status.color = (1,0,0,1)
            except:
                self.ids.status.text ="Error loading path"
                self.ids.status.color = (1,0,0,1)
                self.directory = "/"
        tracks.sort()

        for track in tracks:
            def playTrack(bt):
                try:
                    self.currentlyplaying.stop()
                except:
                    pass
                finally:
                    if track.endswith(".mp3"): 
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.mp3')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text
                    if track.endswith(".wav"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.wav')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text
                    if track.endswith(".aiff"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.aiff')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text
                    if track.endswith(".aac"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.aac')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text
                    if track.endswith(".ogg"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.ogg')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text
                    if track.endswith(".mp4"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.mp4')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text
                    if track.endswith(".wma"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.wma')
                        self.currentlyplaying.play()
                        self.ids.nowplay.text = bt.text

            btn = Button(text = track[:-4], on_press = playTrack)
            self.ids.scroll.add_widget(btn)
            if tracks.index(track) % 2 == 0:
                btn.background_color = (88, 44, 234, 0.6)
            else:
                btn.background_color = (37, 44, 249, 0.6)
            self.soundplayer(*tracks)
        def soundplayer(sound):
            if self.ids.play.state == "down":
                playsound = SoundLoader.load(sound)
                playsound.play()



class PyPlayer(App):
    def build(self):
        player = Player()
        player.Gettrack_path()
        return player   
PyPlayer().run()

还有.kv文件

    #:kivy 1.10
<Player>:

    canvas.before:
        Color:
            rgba: 0,0,0,1
        Rectangle:
            pos: self.pos
            size: self.size

    TextInput:
        id: direct
        pos: 0,root.top-35
        size: (root.width * 0.3),35
        hint_text: 'Browse'

    Button:
        id: searchBtn
        size: (root.width * 0.1),36
        background_color: 1, 0, 0, 22
        pos: root.width * 0.3, root.top-35
        on_release: root.load_tracks()

    ScrollView:
        size_hint: None, None
        size: (root.width *0.4), root.height - 45
        pos: 0, 0
        GridLayout:
            id: scroll
            cols: 1
            spacing: 10
            size_hint_y: None
            row_force_default: True
            row_default_height: 40

    GridLayout:
        rows: 1
        pos: (root.width * 0.4), root.height - 135
        size: (root.width * 0.6), 50
        Button:
            id:previous
            background_color: 0, 0, 0, 1
            Image:
                source: "backward.png"  
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size
        Button:
            id:pause
            background_color: 0, 0, 0, 1
            Image:
                source: "pause.png"
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size
        Button:
            id:play
            on_press: root.soundplayer()
            background_color: 0, 0, 0, 1
            Image:
                source: "play.png"
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size

        Button:
            id:forward
            background_color: 0, 0, 0, 1

            Image:
                source: "forward.png"
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size
    Button:
        id: nowplay
        text: 'Currently Playing'
        pos: (root.width * 0.4),root.height - 85
        size: (root.width * 0.6), 50
        background_color: 0, 0, 0, 0

    Label:
        id: status
        text: ''
        pos: root.width * 0.15, root.top * 0.5

这是我的第一个问题,所以请大家理解我还没有经验

【问题讨论】:

  • 不确定你在问什么。我看到您在 GridLayout 中定义了 4 个按钮,但只为其中一个分配了 on_press 操作。所以没有定义任何动作的三个将有no effect。请清楚您的问题是什么。
  • 我知道必须在每个按钮上使用 on_press 但我的问题是如何为它们编写正确的功能 - 我的按钮如下前一首歌,暂停,播放和下一首歌曲 - 我在想我自己怎么做,但我每次尝试都失败了
  • 因此,您首先在Player 中为每个按钮编写一个方法。使用documentation 寻求帮助。例如,pause 方法可能会从Sound 调用stop() 方法,如果您希望play 从暂停点继续,则可能会调用get_pos() 方法,previousnext 方法是只需停止任何当前播放的声音并在下一首或上一首曲目上调用SoundLoader。您可能需要将您的 tracks 列表作为实例变量,而不是 load_tracks 的本地变量。
  • 谢谢约翰,我会立即在我的代码中尝试你的提示 - 我没有考虑这些方法,我试图将函数直接写入“load_tracks” - 我现在看到了我的错误。感谢您的宝贵时间,周末愉快。完成后我会通知你。

标签: python function button kivy


【解决方案1】:

这花了很长时间,但我忘了发布我的代码 - 也许有人会在自己的项目中学习或重用我的答案:

import kivy
kivy.require('1.10.0')
from kivy.config import Config
Config.set('graphics', 'fullscreen', '0')

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.uix.slider import Slider
from os import listdir, path

Builder.load_file("views/theme.kv")

class Player(Widget):
    directory = "" #directory path;
    currentlyplaying = "" #now playing song;
    position = 0
    volume = 0
    maxvolume = NumericProperty(1.0)
    tracks = []
    def Gettrack_path(self):
        try:
            track = open("path/path.dat", "r")
            self.ids.direct.text = str(track.readline())
            track.close()
            self.ids.searchBtn.text = "Search"
            self.load_tracks()
        except:
           self.ids.direct.text = ''

    def Savetrack_path(self, path):
        track = open("path/path.dat", "w")
        track.write(path)
        track.close()

    def load_tracks(self):
        self.directory = self.ids.direct.text
        if not self.directory.endswith("\\"):
            self.directory += "\\"

        if not path.exists(self.directory):
            self.ids.status.text = "Given path doesn't exist"
            self.ids.status.color = (1,0,0,1)
        else:
            self.ids.status.text = ""
            self.ids.scroll.bind(minimum_height = self.ids.scroll.setter("height"))

        for file in listdir(self.directory):
            if file.endswith(".mp3") or file.endswith(".wav") or file.endswith(".aiff") or file.endswith(".aac") or file.endswith(".ogg") or file.endswith(".mp4") or file.endswith(".wma"):
                self.tracks.append(file)
        if self.tracks == [] and self.directory != "":
            self.ids.status.text = "No tracks found"
            self.ids.status.color = (1,0,0,1)
        if self.directory == "\\" or self.directory == "":
            try:
                self.ids.status.text = "No tracks found - given path doesn't exist"
                self.ids.status.color = (1,0,0,1)
            except:
                self.ids.status.text ="Error loading path"
                self.ids.status.color = (1,0,0,1)
                self.directory = "\\"
        self.tracks.sort()
        for track in self.tracks:
            def playTrack(bt):
                try:
                    self.currentlyplaying.stop()
                except:
                    pass
                finally:
                    if track.endswith(".mp3"): 
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.mp3')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.mp3'
                    if track.endswith(".wav"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.wav')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.wav'
                    if track.endswith(".aiff"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.aiff')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.aiff'
                    if track.endswith(".aac"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.aac')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.aac'
                    if track.endswith(".ogg"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.ogg')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.ogg'
                    if track.endswith(".mp4"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.mp4')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.mp4'
                    if track.endswith(".wma"):
                        self.currentlyplaying = SoundLoader.load(self.directory+bt.text+'.wma')
                        self.currentlyplaying.play()
                        self.currentlyplaying.volume = self.volume
                        self.ids.nowplay.text = bt.text+'.wma'

            btn = Button(text = track[:-4], on_press = playTrack)
            self.ids.scroll.add_widget(btn)
            if self.tracks.index(track) % 2 == 0:
                btn.background_color = (88, 44, 234, 0.6)
            else:
                btn.background_color = (37, 44, 249, 0.6)
    def pause(self):
        if self.ids.pause.state == "down":
            if self.currentlyplaying == "":
                pass
            else:
                self.position = self.currentlyplaying.get_pos()
                self.currentlyplaying.stop()
    def play(self):
        if self.ids.play.state == "down":
            if self.currentlyplaying == "":
                pass
            if self.currentlyplaying.state == "stop":
                self.currentlyplaying.play()
                self.currentlyplaying.volume = self.volume
                self.currentlyplaying.seek(self.position - 1)
            if self.currentlyplaying.state =="play":
                pass
    def next(self):
        if self.ids.forward.state == "down":
            if self.currentlyplaying == "":
                pass
            i = 0
            while(i < len(self.tracks)):
                if self.currentlyplaying.filename == self.directory + self.tracks[i]:
                    self.currentlyplaying.stop()
                    self.currentlyplaying = SoundLoader.load(self.directory + self.tracks[i+1])
                    self.ids.nowplay.text = self.tracks[i+1]
                    self.currentlyplaying.play()
                    self.currentlyplaying.volume = self.volume
                    break
                elif self.currentlyplaying.filename == self.directory + self.tracks[-1]:
                    self.currentlyplaying.stop()
                    self.currentlyplaying = SoundLoader.load(self.directory + self.tracks[0])
                    self.ids.nowplay.text = self.tracks[0]
                    self.currentlyplaying.play()
                    self.currentlyplaying.volume = self.volume
                    break
                i += 1
    def previous(self):
        if self.ids.previous.state == "down":
            if self.currentlyplaying == "":
                pass
            i = 0
        while(i < len(self.tracks)):
                if self.currentlyplaying.filename == self.directory + self.tracks[i]:
                    self.currentlyplaying.stop()
                    self.currentlyplaying = SoundLoader.load(self.directory + self.tracks[i-1])
                    self.ids.nowplay.text = self.tracks[i-1]
                    self.currentlyplaying.play()
                    self.currentlyplaying.volume = self.volume
                    break
                elif self.currentlyplaying.filename == self.directory + self.tracks[0]:
                    self.currentlyplaying.stop()
                    self.currentlyplaying = SoundLoader.load(self.directory + self.tracks[-1])
                    self.ids.nowplay.text = self.tracks[-1]
                    self.currentlyplaying.play()
                    self.currentlyplaying.volume = self.volume
                    break
                i += 1

    def volumectrl(self, *args):
        self.volume = int(args[1]) / 100
        if self.volume >= int(self.maxvolume):
            self.volume = int(self.maxvolume)
        self.currentlyplaying.volume = self.volume


class PyPlayer(App):
    def build(self):
        player = Player()
        player.Gettrack_path()
        return player   
PyPlayer().run()

当然还有一个 .kv 文件:

#:kivy 1.10
<Player>:
    orientation: "horizontal"
    canvas.before:
        Rectangle:
            pos: self.pos
            size: self.size
            source: "264727.jpg"


    TextInput:
        id: direct
        pos: 0,root.top-35
        size: (root.width * 0.3),35
        hint_text: 'balk is empty'

    Button:
        id: searchBtn
        size: (root.width * 0.1),36
        background_color: 1, 0, 0, 22
        pos: root.width * 0.3, root.top-35
        on_release: root.load_tracks()

    ScrollView:
        size_hint: None, None
        size: (root.width *0.4), root.height - 45
        pos: 0, 0
        GridLayout:
            id: scroll
            cols: 1
            spacing: 10
            size_hint_y: None
            row_force_default: True
            row_default_height: 40

    GridLayout:
        rows: 1
        pos: (root.width * 0.4), root.height - 135
        size: (root.width * 0.6), 50
        Button:
            id:previous
            background_color: 0, 0, 0, 0
            on_press: root.previous()
            Image:
                source: "backward.png"  
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size
        Button:
            id:pause
            on_press: root.pause()
            background_color: 0, 0, 0, 0
            Image:
                source: "pause.png"
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size
        Button:
            id:play
            on_press: root.play()
            background_color: 0, 0, 0, 0
            Image:
                source: "play.png"
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size

        Button:
            on_press: root.next()  
            id:forward
            background_color: 0, 0, 0, 0
            Image:
                source: "forward.png"
                y: self.parent.y + self.parent.height - 75
                x: self.parent.x + 10
                size: self.size
    Slider:
        id:volumecontrol
        size_hint_y: 0.1
        pos: (root.width * 0.4), root.height - 200
        size: (root.width * 0.6) - 15, 50
        max: 100
        min: 0
        on_value:root.volumectrl(*args)

    Button:
        id: nowplay
        text: 'Currently Playing'
        pos: (root.width * 0.4),root.height - 85
        size: (root.width * 0.6), 50
        background_color: 0, 0, 0, 0

    Label:
        id: status
        text: ''
        pos: root.width * 0.15, root.top * 0.5

我有什么改变 - 起初我将我的曲目列表替换为 head 类 - 这使它可用于所有功能,并可以将功能写入我的小界面中的所有按钮 - 我在 kv 文件中使用过 a链接到背景图片是什么让它更漂亮了,作为奖励,我编写了一个音量控制函数,并创建了一个条形图,它可以不断读取从 0 到 100 范围内的值

【讨论】:

    猜你喜欢
    • 2022-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2018-10-05
    • 2015-05-01
    • 1970-01-01
    相关资源
    最近更新 更多