Kivy-Если кнопка привязки с обратным вызовом (экземпляр), как вызвать другие функции - PullRequest
0 голосов
/ 09 апреля 2020

То, что я хочу, это:

Нажмите кнопку A >> Открыть диалоговое окно выбора папки >> Выбрать папку A >> Показать путь A в метке A;

Нажмите кнопку B >> Открыть диалог выбора папки >> выберите папку B >> Показать путь B в метке B.

Если вы запустите мой код, он будет работать очень хорошо. Но если вы внимательно прочитаете код, вы обнаружите проблему.

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty

from kivy.lang import Builder
Builder.load_string('''
#:kivy 1.11.0
<Root>:
    loadFolderA: loadFolderA
    loadFolderB: loadFolderB

    cols: 2
    rows: 2
    Button:
        id: selectFolderA
        text: 'select folder A'
        pos_hint: {'center_x': 0.21, 'center_y': .5}
        on_release: root.show_select_folder_dialogA()

    Button:
        id: selectFolderB
        text: 'select folder B'
        pos_hint: {'center_x': 0.785, 'center_y': .5}
        on_release: root.show_select_folder_dialogB()

    Label:
        id: loadFolderA
        text: 'path A'
        font_size: 30
        pos_hint: {'center_x': 0.21, 'center_y': .5}

    Label:
        id: loadFolderB
        text: 'path B'
        font_size: 30
        pos_hint: {'center_x': 0.785, 'center_y': .5}

<SelectFolder>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserListView:
            id: filechooser

        BoxLayout:
            size_hint_y: None
            height: 30
            Button:
                text: "Cancel"
                on_release: root.cancel()

            Button:
                text: "Choose"
                on_release: root.choose(filechooser.path, filechooser.selection)
''')

class Root(GridLayout):
    posixPathA = StringProperty('')
    posixPathB = StringProperty('')

    def dismiss_popup(self):
        self._popup.dismiss()

    def show_select_folder_dialogA(self):
        content = SelectFolder(choose=self.chooseA, cancel=self.dismiss_popup)
        self._popup = Popup(title="Select Folder", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def show_select_folder_dialogB(self):
        content = SelectFolder(choose=self.chooseB, cancel=self.dismiss_popup)
        self._popup = Popup(title="Select Folder", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def chooseA(self, path, filename):
        self.posixPathA = path
        self.loadFolderA.text = self.posixPathA
        self.dismiss_popup()

    def chooseB(self, path, filename):
        self.posixPathB = path
        self.loadFolderB.text = self.posixPathB
        self.dismiss_popup()

class SelectFolder(FloatLayout):
    choose = ObjectProperty(None)
    cancel = ObjectProperty(None)

class DropApp(App):
    def build(self):
        return Root()

if __name__ == '__main__':
    DropApp().run()

Функция 'show_select_folder_dialog', которую я пишу два раза, одна для связывания с кнопкой A, другая для кнопки B. И то же самое для функция «выбрать». Это действительно делает меня несчастным. Поэтому я хочу знать, смогу ли я сообщить Коду, какая кнопка нажата, а затем передать путь к папке с правой меткой. Надеюсь, что кто-то может помочь.

# #

Это занимает всю ночь, теперь я прихожу в это место:

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty

from kivy.lang import Builder
Builder.load_string('''
#:kivy 1.11.0
<Root>:
    loadFolderA: loadFolderA
    loadFolderB: loadFolderB

    cols: 2
    rows: 2
    NewButton:
        id: selectFolderA
        text: 'select folder A'
        pos_hint: {'center_x': 0.21, 'center_y': .5}
        on_release: self.callback()

    NewButton:
        id: selectFolderB
        text: 'select folder B'
        pos_hint: {'center_x': 0.785, 'center_y': .5}
        on_release: self.callback()

    Label:
        id: loadFolderA
        text: 'path A'
        font_size: 30
        pos_hint: {'center_x': 0.21, 'center_y': .5}

    Label:
        id: loadFolderB
        text: 'path B'
        font_size: 30
        pos_hint: {'center_x': 0.785, 'center_y': .5}

<SelectFolder>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserListView:
            id: filechooser

        BoxLayout:
            size_hint_y: None
            height: 30
            Button:
                text: "Cancel"
                on_release: root.cancel()

            Button:
                text: "Choose"
                on_release: root.choose(filechooser.path, filechooser.selection)
''')

class NewButton(Button):
    def __init__(self, **kwargs):
        super(Button, self).__init__(**kwargs)
    def callback(instance):
        print('The button <%s> is being pressed' % instance.text)
        Root.show_select_folder_dialog(Root)

class Root(GridLayout):
    posixPathA = StringProperty('')
    posixPathB = StringProperty('')

    def dismiss_popup(self):
        self._popup.dismiss()

    def show_select_folder_dialog(self):
        content = SelectFolder(choose=self.choose, cancel=self.dismiss_popup)
        self._popup = Popup(title="Select Folder", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def choose(self, path, filename):
            self.posixPathA = path
            self.loadFolderA.text = self.posixPathA
            self.dismiss_popup()


class SelectFolder(FloatLayout):
    choose = ObjectProperty(None)
    cancel = ObjectProperty(None)

class DropApp(App):
    def build(self):
        return Root()

if __name__ == '__main__':
    DropApp().run()

Мой план состоит в том, чтобы использовать Callback (экземпляр), чтобы узнать, какая кнопка вызывала функция. Затем вызовите функцию, чтобы открыть диалог выбора папки. Странно, но эта строка работает здесь:

Root.show_select_folder_dialog(Root)

Но я не могу go дальше. Теперь функция сообщает об ошибке: «TypeError: choose () отсутствует 1 обязательный позиционный аргумент:« имя файла »'

Надеюсь, кто-то может мне помочь!

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Вы можете удалить оба дублированных метода A / B, отправив idx нажатием кнопки:


Builder.load_string('''
#:kivy 1.11.0
<Root>:
    loadFolderA: loadFolderA
    loadFolderB: loadFolderB

    cols: 2
    rows: 2
    Button:
        id: selectFolderA
        text: 'select folder A'
        pos_hint: {'center_x': 0.21, 'center_y': .5}
        on_release: root.show_select_folder_dialog("A")  # send an idx here

    Button:
        id: selectFolderB
        text: 'select folder B'
        pos_hint: {'center_x': 0.785, 'center_y': .5}
        on_release: root.show_select_folder_dialog("B")  # send an idx here

    Label:
        id: loadFolderA
        text: 'path A'
        font_size: 30
        pos_hint: {'center_x': 0.21, 'center_y': .5}

    Label:
        id: loadFolderB
        text: 'path B'
        font_size: 30
        pos_hint: {'center_x': 0.785, 'center_y': .5}

<SelectFolder>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserListView:
            id: filechooser

        BoxLayout:
            size_hint_y: None
            height: 30
            Button:
                text: "Cancel"
                on_release: root.cancel()

            Button:
                text: "Choose"
                on_release: root.choose(filechooser.path, filechooser.selection)
''')

from functools import partial

class Root(GridLayout):
    posixPathA = StringProperty('')
    posixPathB = StringProperty('')

    def dismiss_popup(self):
        self._popup.dismiss()

    def show_select_folder_dialog(self, idx):
        # pass the idx to the choose method
        content = SelectFolder(choose=partial(self.choose, idx),
                               cancel=self.dismiss_popup)
        self._popup = Popup(title="Select Folder", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def choose(self, idx, path, filename):
        if idx == "A":  # The "A" button was selected
            self.posixPathA = path
            self.loadFolderA.text = self.posixPathA
        else:  # You can use more elifs if you like
            self.posixPathB = path
            self.loadFolderB.text = self.posixPathB
        self.dismiss_popup()

class SelectFolder(FloatLayout):
    choose = ObjectProperty(None)
    cancel = ObjectProperty(None)

class DropApp(App):
    def build(self):
        return Root()

if __name__ == '__main__':
    DropApp().run()
0 голосов
/ 09 апреля 2020

Привет, друг, у меня есть простое решение для твоего кода, которое облегчает распознавать, какую кнопку ты выбрал, для которой ты можешь использовать простой gui модуль:

choice = easygui.buttonbox(title="Choose button",msg="Choose a button",choices=["Button 1","Button 2",]) 

, который открывает окно, подобное :

enter image description here

И теперь вы можете использовать условие if для выполнения остальной части процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...