【问题标题】:Kivy Python TextInput display BubbleKivy Python TextInput 显示气泡
【发布时间】:2018-05-13 03:49:16
【问题描述】:

我正在尝试在 Kivy 中为 TextInput 显示气泡中的数字键盘。可能吗? 到目前为止,我有:

Builder.load_string('''
<NumericKeyboard>
size_hint: (None, None)
size: (160, 120)
pos_hint: {'center_x': .5, 'y': .6}
BubbleButton:
    text: 'Cut'
BubbleButton:
    text: 'Copy'
BubbleButton:
    text: 'Paste'
''')

class NumericKeyboard(Bubble):
    pass

class CustomTextInput(TextInput):
def __init__(self, **kwargs):
    super(CustomTextInput, self).__init__(**kwargs)

def on_focus(self, instance, value):
    self.bubb = NumericKeyboard()
    self.add_widget(self.bubb)

但气泡不会显示。

【问题讨论】:

    标签: python python-3.x kivy


    【解决方案1】:

    是的,可以使用 Kivy Bubble 为 TextInput 小部件显示数字键盘。详情请参考以下示例。

    注意:文本输入没有被过滤。

    示例

    main.py

    ​​>
    from kivy.app import App
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.bubble import Bubble, BubbleButton
    from kivy.uix.label import Label
    from kivy.properties import ObjectProperty
    from kivy.lang import Builder
    
    
    class CustomBubbleButton(BubbleButton):
        pass
    
    
    class NumericKeyboard(Bubble):
        layout = ObjectProperty(None)
    
        def __init__(self, **kwargs):
            super(NumericKeyboard, self).__init__(**kwargs)
            self.create_bubble_button()
    
        def create_bubble_button(self):
            numeric_keypad = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '', '0', '.']
            for x in numeric_keypad:
                if len(x) == 0:
                    self.layout.add_widget(Label(text=""))
                else:
                    bubb_btn = CustomBubbleButton(text=str(x))
                    self.layout.add_widget(bubb_btn)
    
    
    class BubbleShowcase(FloatLayout):
        text_input = ObjectProperty(None)
    
        def show_bubble(self, *l):
            if not hasattr(self, 'bubb'):
                self.bubb = bubb = NumericKeyboard()
                self.bubb.arrow_pos = "bottom_mid"
                self.add_widget(bubb)
    
    
    Builder.load_file("test.kv")
    
    
    class TestBubbleApp(App):
        title = "Numeric Key Pad - Using Bubble"
    
        def build(self):
            return BubbleShowcase()
    
    
    if __name__ == '__main__':
        TestBubbleApp().run()
    

    test.kv

    #:kivy 1.10.0
    
    <CustomBubbleButton>:
        on_release:
            app.root.text_input.text += self.text
    
    
    <NumericKeyboard>:
        layout: layout
    
        size_hint: (None, None)
        size: (160, 120)
        pos_hint: {'center_x': .5, 'y': .6}
    
        GridLayout:
            id: layout
            cols: 3
    
    <BubbleShowcase>:
        text_input: text_input
    
        canvas:
            Color:
                rgba: 0, 1, 1, 1
            Rectangle:
                size: self.width, self.height
        TextInput:
            id: text_input
            pos_hint: {'center_x': .5, 'y': .54}
            size_hint: (0.2, 0.06)
            cursor_blink: True
            font_size: 20
            multiline: False
            on_focus:
                root.show_bubble()
    

    输出

    【讨论】:

      【解决方案2】:

      谢谢@ikolim 代码和解释,我做了一些改进和大家分享。

      1. 替换了kivy提供的图片背景
      2. canvas 和 padding 指定,做圆角矩形外观
      3. 切记:客户小部件在Bubble Widget中添加,Bubble Widget必须在FloatLayout中添加
      4. 代码运行在win10-64,kivy2.0.0,py366(如有问题请小修改)bubble_arrow_up.png Show resultsbubble_down.png delete.png

      mycalculate.py

      # !/usr/bin/env python  
      # -*- coding: utf-8 -*- 
      from functools import partial
      
      from kivy.app import App
      from kivy.core.window import Window
      from kivy.core.text import LabelBase
      from kivy.uix.bubble import Bubble, BubbleButton
      from kivy.properties import ObjectProperty
      from kivy.uix.boxlayout import BoxLayout
      
      
      class NumBubbleButton(BubbleButton):
          pass
      
      
      class Calculate(Bubble):
          content = ObjectProperty("")
      
          def __init__(self, **kwargs):
              super(Calculate, self).__init__(**kwargs)
              self.create_keyboard()
      
          def create_keyboard(self):
              num_key = ['7', '8', '9', '4', '5', '6', '1', '2', '3', ' ', '0', '⌫']
              for x in num_key:
                  btn = NumBubbleButton(text=str(x))
                  btn.bind(on_press=partial(self.add_text, str(x)))
                  if x == " ":
                      btn.disabled = True
                      btn.background_disabled_normal = ""
                  elif x == "⌫":
                      btn.text = ""
                      btn.background_normal = "delete.png"
                  self.ids.calculator.add_widget(btn)
          @staticmethod
          def add_text(text, *args):
              print(text)
      
      class Cale(BoxLayout):
          def __init__(self, **kwargs):
              super(Cale, self).__init__(**kwargs)
      
              self.cale = Calculate()
              self.cale.width, self.cale.height = 200, 400
              self.ids.float_grid.add_widget(self.cale)
      
      class MyCalculateApp(App):
          def __init__(self, **kwargs):
              super(MyCalculateApp, self).__init__(**kwargs)
      
          def build(self):
              # Window.fullscreen = False
              # Window.left, Window.top, Window.size = 10, 0, (300, 500)
              return Cale()
      
      if __name__ == "__main__":
          MyCalculateApp().run()
      

      mycalculate.kv

      <NumBubbleButton>:
          background_normal: ""
          background_color: 1, 1, 1, 1
          color: 0, 0, 0, 1
          bold: True
          font_size: "48px"
      <Calculate>:
          size_hint: None, None
          orientation: "vertical"
          arrow_image: "bubble_arrow_up.png"
          background_image: "bubble_down.png"
          arrow_pos: "top_mid"
      
      
          BoxLayout:
              padding: 5, 5, 5, 0
              size_hint: 1, 1
      
              GridLayout:
                  id: calculator
                  canvas:
                      Color:
                          rgba: 232/255, 232/255, 232/255, 1
                      Rectangle:
                          pos: self.pos
                          size: self.size
                  spacing: 2
                  rows: 5
                  cols: 3
          BoxLayout:
              size_hint: 1, 0.2
              padding: 5
              canvas.before:
                  Color:
                      rgba: 199/255, 31/255, 58/255, 1
                  RoundedRectangle:
                      pos: self.pos
                      size: self.size
                      radius: [0, 0, 10, 10]
              Button:
                  background_normal: ""
                  background_color: 199/255, 31/255, 58/255, 1
                  font_size: "32px"
                  text: t.t("Confirm")
                  markup: True
                  on_press: print("Confirm")
      <Cale>:
          FloatLayout:
              id: float_grid
              GridLayout:
                  id: grid_goods
      

      【讨论】:

        【解决方案3】:

        您不能将小部件添加到文本输入,因为它不是布局。您应该将文本输入添加到布局,然后将气泡添加到此布局。试试这个:

        from kivy.app import App
        from kivy.uix.bubble import Bubble
        from kivy.uix.textinput import TextInput
        from kivy.lang import Builder
        from kivy.uix.floatlayout import FloatLayout
        
        Builder.load_string('''
        <NumericKeyboard>
            size_hint: (None, None)
            size: (160, 120)
            pos_hint: {'center_x': .5, 'y': .6}
            BubbleButton:
                text: 'Cut'
            BubbleButton:
                text: 'Copy'
            BubbleButton:
                text: 'Paste'
        ''')
        
        class NumericKeyboard(Bubble):
            pass
        
        
        class CustomTextInputLayout(FloatLayout):
            def __init__(self, **kwargs):
                super(CustomTextInputLayout, self).__init__(**kwargs)
                self.add_widget(CustomTextInput(self))
        
        
        class CustomTextInput(TextInput):
            def __init__(self, layout,**kwargs):
                super(CustomTextInput, self).__init__(**kwargs)
                self.layout = layout
        
            def on_focus(self, instance, value):
                self.bubb = NumericKeyboard()
                self.layout.add_widget(self.bubb)
        
        class MyTestApp(App):
            def build(self):
                return CustomTextInputLayout()
        
        if __name__ == '__main__':
            MyTestApp().run()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-13
          • 1970-01-01
          • 2021-01-19
          • 1970-01-01
          • 1970-01-01
          • 2021-03-26
          • 2017-04-04
          • 2014-11-10
          相关资源
          最近更新 更多