Kivy/Python 文本输入焦点

Posted

技术标签:

【中文标题】Kivy/Python 文本输入焦点【英文标题】:Kivy/Python TextInput Focus 【发布时间】:2021-10-01 12:59:58 【问题描述】:

在我的基本除法计算器应用程序中,我有 2 个不同的文本输入框和一个小屏幕键盘。但是,每当在屏幕键盘上的应用程序中按下一个数字时,两个框都会填充完全相同的数字

这是我遇到问题的部分

#creating the button number function  
        def buttonText(instance): #creating an output to print the button text 
            if entrnum1.get_focus_previous(): 
                entrnum1.text += instance.text
            if entrnum2.get_focus_previous(): 
                entrnum2.text += instance.text

这是完整的代码:

import kivy #importing kivy and various tools needed 
from kivy.app import App
from kivy.uix.label import Label 
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.graphics import * 
from kivy.uix.textinput import TextInput
from kivy.core.window import Window #setting the window size in kivy 
from kivy.uix.checkbox import CheckBox
from kivy.uix.dropdown import DropDown
from kivy.config import Config # allows usage of custom made icons 
from kivy.uix.behaviors.focus import FocusBehavior

Window.size=(360,600) # setting the window size 
class divCalc(RelativeLayout):
    
    layoutHome = RelativeLayout()
    def __init__(self,**kwargs):#creating the constructor 
        super(divCalc, self).__init__(**kwargs)
        
        layoutHome = RelativeLayout()
        def div(self):
            lblcalc= Label(text="Division Calculator",size_hint=(0.3,0.1), pos_hint='x':0.12, 'y':0.9,color=(.9,.9,.9,1))
            layoutHome.add_widget(lblcalc)
            
            lblnum1 = Label(text="num1 ",size_hint=(0.3,0.1), pos_hint='x':0.15, 'y':0.8,color=(.9,.9,.9,1))
            layoutHome.add_widget(lblnum1)
            entrnum1 = TextInput(size_hint=(0.3,0.06), pos_hint='x':0.48, 'y':0.82, multiline=False, cursor_color=(0,0,0,1))
            layoutHome.add_widget(entrnum1)
            
            lblnum2 = Label(text="num2 ",size_hint=(0.3,0.1), pos_hint='x':0.15, 'y':0.74,color=(.9,.9,.9,1))
            layoutHome.add_widget(lblnum2)
            entrnum2 = TextInput(size_hint=(0.3,0.06), pos_hint='x':0.48, 'y':0.76, multiline=False, cursor_color=(0,0,0,1))
            layoutHome.add_widget(entrnum2)
            
            lblans = Label(text="answer",size_hint=(0.3,0.1), pos_hint='x':0.15, 'y':0.68,color=(.9,.9,.9,1))
            layoutHome.add_widget(lblans)
            
            txtAnswer = TextInput(size_hint=(0.3,0.058), pos_hint='x':0.48, 'y':0.7, multiline=False, disabled=True,#disabled sets text input to read only 
                                    background_disabled_normal='', background_color=(0.91,0.91,0.031,0.9),disabled_foreground_color=(0,0,0,1),
                                    font_size=20)#setbackground disabled to white first to avoid grey tint 
            layoutHome.add_widget(txtAnswer)
        
            def supplyCalc(self):
                try: #try catch loop for user errors 
                    oneNum = float(entrnum1.text)#Converting TextInput to Float 
                    twoNum = float(entrnum2.text)
                    
                    answer = round(oneNum/twoNum,5) #rounding the answer to 5 decimal places
                    txtAnswer.text = str((answer))#converting the answer back to a string and placing into text input box 
                except:
                    answer = "ERROR" #if exception is thrown then give error for answer 
                    txtAnswer.text = answer
            
            btnCalculate = Button(text="Calculate",size_hint=(0.3,0.1), pos_hint='x':0.53, 'y':0.59,color=(.9,.9,.9,1),background_color=(.8,.8,.8,1))
            btnCalculate.bind(on_press=supplyCalc)
            layoutHome.add_widget(btnCalculate)  
            
            #creating the button number function  
            def buttonText(instance): #creating an output to print the button text 
                if entrnum1.get_focus_previous():  #partially working, need to figure out how to get focus on textinput 
                    entrnum1.text += instance.text
                if entrnum2.get_focus_previous(): 
                    entrnum2.text += instance.text
            
            def clearAll(self): #clearing all the text off the screen 
                entrnum1.text = ''
                entrnum2.text = ''
                txtAnswer.text = '' 
            def backSpace(self):
                pass
              
            buttonsNums = [7,8,9,4,5,6,1,2,3,0] #creating an empty list for the buttons 
            
            y = 0.35 #setting the initial value for y 
            x = 0.2 # setting the initial value for x 
            i=1 #creating a counter for i to newline after every 3rd button 
            #creating a for loop to create the buttons 
            for num in buttonsNums:
                btnCalc = Button(text=str(num),size_hint=(0.2,0.1), pos_hint='x':x, 'y':y)
                btnCalc.bind(on_press=buttonText)#binding the button to then set to its text
                layoutHome.add_widget(btnCalc) 
                x+=0.19
                
                if i%3 == 0:#if 1 divided by 3 has 0 remainder new row
                    y-=0.10
                    x=0.2 
                i+=1
                
                btnDecimal = Button(text=".",size_hint=(0.39,0.1), pos_hint='x':0.39, 'y':0.05)
                btnDecimal.bind(on_release=buttonText)
                layoutHome.add_widget(btnDecimal)
                
                btnBackspace = Button(text="<--",size_hint=(0.2,0.1), pos_hint='x':0.2, 'y':0.45)
                btnBackspace.bind(on_release=backSpace)
                layoutHome.add_widget(btnBackspace) #THIS BUTTON CURRENT STILL NEEDS WORK 
                
                btnClearAll = Button(text="Clear All",size_hint=(0.39,0.1), pos_hint='x':0.39, 'y':0.45)
                btnClearAll.bind(on_release=clearAll)
                layoutHome.add_widget(btnClearAll)
        div(self)
        self.add_widget(layoutHome)
    

    class miniCalc(App): #building the application (night mode, default)
        def build(self):
            return divCalc()    
    if __name__ == "__main__": #running the application 
        miniCalc().run()

非常感谢您的帮助

【问题讨论】:

【参考方案1】:

找到了解决办法,

所以 textInput 小部件在您触发小部件时会自动放弃焦点,这意味着 unfocus_on_touch 默认设置为 true 给定某些参数,因此需要像这样将其更改为 false

        entrnum1 = TextInput(size_hint=(0.3,0.06), unfocus_on_touch=False, pos_hint='x':0.48,'y':0.82, multiline=False, cursor_color=(0,0,0,1))
        layoutHome.add_widget(entrnum1)

还需要更改 buttonText 函数上的 if 语句:

#creating the button number function  
            def buttonText(instance): #creating an output to print the button text 
                if entrnum1.focus == True:  #partially working, need to figure out how to get focus on textinput 
                    entrnum1.text += instance.text
                if entrnum2.focus == True: 
                    entrnum2.text += instance.text

我找到了一个很好的 kivy 参考

https://buildmedia.readthedocs.org/media/pdf/kivy/master/kivy.pdf

【讨论】:

以上是关于Kivy/Python 文本输入焦点的主要内容,如果未能解决你的问题,请参考以下文章

在 Kivy Python 中使用预定义值创建文本输入

Kivy,Python3.5 - 将用户文本输入绑定到类中的方法

Kivy Python-文本输入框填充整个浮动布局屏幕

如何将文本输入值添加到kivy python中字典中的值?

如何在 kivy python 中的标签、文本输入和其他小部件中添加标题

无法在 KIVY Python 中打印取自 kivy.uix.textinput.TextInput 的文本