有没有一种方法可以创建一个气泡弹出窗口,用于将文本输入到不同的文本输入中?

2024-09-19 23:42:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图创建一个标准的数字键盘,当用户触摸屏幕上的文本输入时会弹出,这样用户就可以不用鼠标和键盘输入数字值。我一直在问this问题,这个问题允许在一个文本框中输入值,但是当我试图用它在多个文本输入中输入值时,我无法让程序正常运行。我仅限于使用Python,而不是Kivy语言,因此我可以理解编写代码有点笨拙。你知道吗

我的计划是为Bubble(inputbuble)、Bubble按钮(inputbublebuttons)和文本输入框(text\u inputs)创建一个类,其中text\u inputs小部件从RHS()调用一个函数(我的主要布局之一),该函数应该显示Bubble。我似乎无法复制app.root.text\u输入.text+=self.text文件从试验电压(kv)文件,所以我当前的错误是“text\u inputs object has no attribute'bubblein'”,我想不出一个方法来跳过这个。你知道吗

import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.bubble import Bubble, BubbleButton

class inputBubble(Bubble):
        def __init__(self, **kwargs):
                super(inputBubble, self).__init__(**kwargs)
                inputGrid = GridLayout(cols = 3)
                keypad_numbers = ['7', '8', '9', '4', '5', '6', '1', '2', '3', 'CLR', '0', '.']
                for x in keypad_numbers:
                        inputGrid.add_widget = inputBubbleButtons(text = x)
                self.add_widget(inputGrid)

class inputBubbleButtons(BubbleButton):
        def __init__(self, **kwargs):
                super(inputBubbleButtons, self).__init__(**kwargs)
                self.on_release = self.buttonfunctions

        def buttonfunctions(self):
                if self.text != 'CLR':
                        text_input.text += self.text
                else:
                        text_input.text = '0'

class text_inputs(TextInput):
        def __init__(self, **kwargs):
                super(text_inputs, self).__init__(**kwargs)
                self.id = 'text_input'
                self.cursor_blink = False
                self.multiline = False
                self.on_focus = RHS.show_input(self)

class RHS(BoxLayout):
        def __init__(self, **kwargs):
                super(RHS, self).__init__(**kwargs)
                nangleRow = BoxLayout(orientation = 'horizontal')
                self.add_widget(nangleRow)
                nangleRow.add_widget(Label(text = 'New Angle'))
                nangleInput = text_inputs()
                nangleRow.add_widget(nangleInput)

        def show_input(self, *l):
                if not hasattr(self, 'bubblein'):
                        bubblein = inputBubble()
                        self.bubblein.arrow_pos = "bottom_mid"
                        self.add_widget(bubblein)

class Root(GridLayout):
        def __init__(self, **kwargs):
                super(Root, self).__init__(**kwargs)
                self.cols = 1
                self.add_widget(RHS(),0)

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

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

当焦点在nangleInput上时,我希望这会创建一个气泡,但是我得到错误消息“AttributeError:'text\u inputs'object has no attribute'bubblein'”。你知道吗


Tags: textfromimportselfaddinitdefwidget
1条回答
网友
1楼 · 发布于 2024-09-19 23:42:38

以下是您的代码版本,我认为它符合您的要求:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.bubble import Bubble, BubbleButton

class inputBubble(Bubble):
        def __init__(self, **kwargs):
                super(inputBubble, self).__init__(**kwargs)
                inputGrid = GridLayout(cols = 3)
                keypad_numbers = ['7', '8', '9', '4', '5', '6', '1', '2', '3', 'CLR', '0', '.']
                for x in keypad_numbers:
                        inputGrid.add_widget(inputBubbleButtons(text = x))    # use add_widget to add each Button to the inputGrid
                self.add_widget(inputGrid)

class inputBubbleButtons(BubbleButton):
        def __init__(self, **kwargs):
                super(inputBubbleButtons, self).__init__(**kwargs)
                self.on_release = self.buttonfunctions

        def buttonfunctions(self):
                if self.text != 'CLR':
                        # complex path to the TextInput
                        App.get_running_app().root.RHS.nangleInput.text += self.text
                else:
                        App.get_running_app().root.RHS.nangleInput.text = '0'

class text_inputs(TextInput):
        def __init__(self, **kwargs):
                super(text_inputs, self).__init__(**kwargs)
                self.id = 'text_input'
                self.cursor_blink = False
                self.multiline = False

class RHS(BoxLayout):
        def __init__(self, **kwargs):
                super(RHS, self).__init__(**kwargs)
                nangleRow = BoxLayout(orientation = 'horizontal')
                self.add_widget(nangleRow)
                nangleRow.add_widget(Label(text = 'New Angle'))
                self.nangleInput = text_inputs()    # save a reference to text_inputs
                self.nangleInput.bind(focus=self.show_input)    # use bind to get method called when focus changes
                nangleRow.add_widget(self.nangleInput)

        def show_input(self, *l):
                if not hasattr(self, 'bubblein'):
                        self.bubblein = inputBubble()    # create attribute that is tested for in above line
                        self.bubblein.arrow_pos = "bottom_mid"
                        self.add_widget(self.bubblein)

class Root(GridLayout):
        def __init__(self, **kwargs):
                super(Root, self).__init__(**kwargs)
                self.cols = 1
                self.RHS = RHS()    # save  reference to RHS
                self.add_widget(self.RHS,0)

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

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

问题包括:

  1. inputGrid.add_widget = inputBubbleButtons(text = x)应该是inputGrid.add_widget(inputBubbleButtons(text = x))。你知道吗
  2. buttonfunctions()中,引用text_input,但尚未定义。我用一个相当复杂的路径替换了它,它指向实际的text_inputs。你知道吗
  3. self.on_focus = RHS.show_input(self)运行show_input()方法并将返回值(即None)赋给self.on_focus。我已经删除了这一行,并将self.nangleInput.bind(focus=self.show_input)放在RHS类中,我认为这实现了您的意图。你知道吗
  4. show_inputs()方法中,您正在检查名为bubblein的属性是否存在,但是您的代码没有创建一个属性。我已经将if块中的第一行更改为self.bubblein = inputBubble(),这将创建该属性。其他更改也可以访问新属性。你知道吗
  5. Root类中,我保存了对创建的RHS实例的引用,以便在其他地方使用。你知道吗

如果要使用多个TextInput实例,可以调整小键盘的目标以将文本发送到不同的TextInputs。下面是代码的另一个版本:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.bubble import Bubble, BubbleButton

class inputBubble(Bubble):
        def __init__(self, text_input, **kwargs):
                super(inputBubble, self).__init__(**kwargs)
                self.inputGrid = GridLayout(cols = 3)    # save a reference to the grid of inputBubbleButtons
                keypad_numbers = ['7', '8', '9', '4', '5', '6', '1', '2', '3', 'CLR', '0', '.']
                for x in keypad_numbers:
                        self.inputGrid.add_widget(inputBubbleButtons(text_input, text = x))    # use add_widget to add each Button to the inputGrid
                self.add_widget(self.inputGrid)

        # this method changes the target TextInput of the keypad
        def set_text_input(self, text_input):
                for butt in self.inputGrid.children:
                        butt.text_input = text_input

class inputBubbleButtons(BubbleButton):
        def __init__(self, text_input, **kwargs):
                self.text_input = text_input    # the target TextInput
                super(inputBubbleButtons, self).__init__(**kwargs)
                self.on_release = self.buttonfunctions

        def buttonfunctions(self):
                if self.text != 'CLR':
                        self.text_input.text += self.text
                else:
                        self.text_input.text = '0'

class text_inputs(TextInput):
        def __init__(self, **kwargs):
                super(text_inputs, self).__init__(**kwargs)
                self.id = 'text_input'
                self.cursor_blink = False
                self.multiline = False

class RHS(BoxLayout):
        def __init__(self, **kwargs):
                super(RHS, self).__init__(**kwargs)
                self.orientation = 'vertical'
                self.bubblein = None
                for i in range(5):
                        nangleRow = BoxLayout(orientation = 'horizontal')
                        self.add_widget(nangleRow)
                        nangleRow.add_widget(Label(text = 'New Angle ' + str(i)))
                        self.nangleInput = text_inputs()    # save a reference to text_inputs
                        self.nangleInput.bind(focus=self.show_input)    # use bind to get method called when focus changes
                        nangleRow.add_widget(self.nangleInput)

        def show_input(self, text_input, has_focus):
                if has_focus:
                        if self.bubblein is not None:
                                # already have a keypad, just change the target TextInput to receive the key strokes
                                self.bubblein.set_text_input(text_input)
                        else:
                                self.bubblein = inputBubble(text_input)
                                self.bubblein.arrow_pos = "bottom_mid"
                                self.add_widget(self.bubblein)

class Root(GridLayout):
        def __init__(self, **kwargs):
                super(Root, self).__init__(**kwargs)
                self.cols = 1
                self.RHS = RHS()    # save  reference to RHS
                self.add_widget(self.RHS,0)

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

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

相关问题 更多 >