首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Kivy应用程序获取用户输入,并使用Python将其附加到google工作表

从Kivy应用程序获取用户输入,并使用Python将其附加到google工作表
EN

Stack Overflow用户
提问于 2021-04-01 01:06:02
回答 1查看 566关注 0票数 0

我正在尝试制作一个简单的Python应用程序(使用一个kv文件作为布局),我将使用它来保存我的工作部件的库存。我对python和kivy非常陌生,所以我需要一点方向。

其中一个基本功能是允许用户在“添加部件到库存”屏幕(四个屏幕之一)上输入一个新的部件。用户输入由四个项目组成(部件名称、序列号、在手数量和所需的最小数量)。

一旦用户输入这个信息并按下'Submit‘按钮,我希望该数据被附加到google工作表中的一个新行中,我正在使用Google /Sheets API作为后端数据库(我能够工作)。

我在网上找到的大多数示例应用程序只有一个屏幕,并且只处理一种类型的用户输入(通常是文本,而我的输入将是文本和整数)。

我感到困惑的是,我需要将I放在kv文件中的哪里(假设在AddPartWindow布局下)、如何在根类中按下按钮时调用函数、如何将用户输入存储到列表中,因为我不知道ObjectProperty函数到底在做什么,最后,如何将该列表附加到google中的新行。

我没有寻找一个剪切和粘贴的答案,只是一些方向将是很好的,因为我还没有找到一个好的参考,我正试图做什么。我的主要困惑在于有多个屏幕,以及如何在不同屏幕和它们各自的类之间传输数据。数据应该只通过一个根类来传递吗?或者每个类可以用来处理来自应用程序中各自屏幕(窗口)的数据?ObjectProperty函数到底在做什么?我发现kivy网站在描述属性类时有点费解。

任何帮助/指导都会受到极大的感谢。

以下是main.py代码:

代码语言:javascript
复制
import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = ['https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('My_First_Project-3d753d98320e.json', scope)
client = gspread.authorize(creds)
iQue_sheet = client.open("InventoryBackend").sheet1

#root layout
class InventoryWindow(Screen):
    pass

#Layout in question
class AddPartWindow(Screen):

    #Is there anything else I need to do with these before saving into a list or dictionary?
    
    part_name = ObjectProperty(None)
    serial_number = ObjectProperty(None)
    on_hand_cnt = ObjectProperty(None)
    min_needed = ObjectProperty(None)

    #This function should save the user input into a list, np, and then append to the google sheet iQue_sheet
    #Wasn't sure if it should be a list or a dictionary.
    #I'm assuming .text is type-casting each object to a string.  Can this be used for numerical inputs?
    
    def new_part(self):
        np = [self.part_name.text, self.serial_number.text, self.on_hand_cnt.text, self.min_needed.text]
        iQue_sheet.append(np)

class OnOrderWindow(Screen):
    pass

class OrderFormWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

class InventoryApp(App):
    def build(self):
        #These are used to enable going back and forth between screens using buttons
        sm = ScreenManager()
        sm.add_widget(InventoryWindow(name='inv_window'))
        sm.add_widget(OnOrderWindow(name='on_order_window'))
        sm.add_widget(AddPartWindow(name='add_part_window'))
        sm.add_widget(OrderFormWindow(name='order_form_window'))
        return sm

if __name__ == "__main__":
    InventoryApp().run()

下面是布局的my .kv文件,Add窗口是最后一个布局:

代码语言:javascript
复制
WindowManager:
    InventoryWindow:
    OnOrderWindow:
    OrderFormWindow:
    AddPartWindow:

<ItemLabel@Label>
    font_size: '15sp'
    halign: 'left'
    valign: 'middle'
    text_size: self.size

<ItemButton@Button>
    pos_hint: {'center_x':0.5, 'center_y':0.5}
    size_hint: 0.65, 0.2


<ItemButton2@Button>
    pos_hint: {'center_x':0.5, 'center_y':0.5}
    size_hint: 0.65, 0.2
    on_release:
        app.root.current = "order_form_window"


<InventoryWindow>:
    name: "inv_window"
        add_probe: add_probe

    FloatLayout:
        Label:
            text: 'Inventory'
            font_size: '25sp'
            size_hint: (1, 0.17)
            pos_hint: {'x': 0, 'y': 0.87}

    GridLayout:
        cols: 4

        padding:[10, 65, 10, 10]
        spacing: 5

        BoxLayout:
            orientation: 'vertical'
            ItemLabel:
                text:'iQue3: Probe/Tubing'

        BoxLayout:
            orientation: 'vertical'

            ItemButton:
                text:'Add'
                on_release:
                    root.new_part()

        BoxLayout:
            orientation: 'vertical'

            ItemButton:
                text:'Sub'

        BoxLayout:
            orientation: 'vertical'
            ItemButton2:
                text:'Order'

        BoxLayout:
            orientation: 'vertical'
            ItemLabel:
                text:'Gen2: Probe/Tubing'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Add'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Sub'

        BoxLayout:
            orientation: 'vertical'
            ItemButton2:
                text:'Order'

        BoxLayout:
            orientation: 'vertical'
            ItemLabel:
                text:'Beads'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Add'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Sub'

        BoxLayout:
            orientation: 'vertical'
            ItemButton2:
                text:'Order'

        BoxLayout:
            orientation: 'vertical'
            ItemLabel:
                text:'iQue3 Fluid Maint. Kit'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Add'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Sub'

        BoxLayout:
            orientation: 'vertical'
            ItemButton2:
                text:'Order'

        BoxLayout:
            orientation: 'vertical'
            ItemLabel:
                text:'Screener Fluid Maint. Kit'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Add'

        BoxLayout:
            orientation: 'vertical'
            ItemButton:
                text:'Sub'

        BoxLayout:
            orientation: 'vertical'
            ItemButton2:
                text:'Order'

        BoxLayout:
            orientation: 'vertical'


    GridLayout:
        cols: 2
        size_hint: 1, 0.15
        padding: [10, 0, 10, 10]


        BoxLayout:

            Button:
                text: 'Add Part to Inventory'
                font_size: '18sp'
                size_hint: (1, 0.75)
                on_release:
                    app.root.current = "add_part_window"
                    root.manager.transition.direction = "right"

            Button:
                text: 'On Order'
                font_size: '18sp'
                size_hint: (1, 0.75)
                on_release:
                    app.root.current = "on_order_window"
                    root.manager.transition.direction = "left"


<OnOrderWindow>:

    name: "on_order_window"

    FloatLayout:
        Label:
            text: 'On Order'
            font_size: '25sp'
            size_hint: (1, 0.17)
            pos_hint: {'x': 0, 'y': 0.87}

        GridLayout:
            cols: 2
            size_int: 1, .15
            padding:[10, 510, 10, 10]

            Button:
                text: "Inventory"
                font_size: '18sp'
                size_hint: (1, 0.6)
                on_release:
                    app.root.current = "inv_window"
                    root.manager.transition.direction = "right"
            Button:
                text:"Add Part to Inventory"
                size_hint: (1, 0.6)
                font_size: '18sp'
                on_release:
                    app.root.current = "add_part_window"
                    root.manager.transition.direction = "left"


<OrderFormWindow>
    name: "order_form_window"

    FloatLayout:
        Label:
            text: 'Order Form'
            font_size: '25sp'
            size_hint: (1, 0.17)
            pos_hint: {'x': 0, 'y': 0.87}

        GridLayout:
            cols:2
            padding: [50, 50, 50, 120]

            ItemLabel:
                text: "Part: "

            ItemLabel:
                text: "Populate Part Here"

            ItemLabel:
                text: "Serial Number: "

            ItemLabel:
                text: "Populate SN Here"

            ItemLabel:
                text: "On Hand: "

            ItemLabel:
                text: "Populate On Hand Count Here"

            ItemLabel:
                text: "Minimum Needed: "

            ItemLabel:
                text: "Populate Min Needed Here"

            ItemLabel:
                text: "Order Quantity"

            TextInput:
                halign: 'left'
                valign: 'middle'
                input_type: 'number'
                input_filter: 'int'
                multiline:False

        GridLayout:
            cols:2
            size_hint: 1, 0.15
            padding: [10, 0, 10, 10]

            Button:
                text:"Cancel"
                on_release: app.root.current = "inv_window"

            Button:
                text:"Submit Order"
                on_release: app.root.current = "on_order_window"


#This is the add part screen layout I'm referring to
<AddPartWindow>
    name: "add_part_window"

        #These are the id's I was referring to:
        
        part_name: part_name
        serial_number: serial_number
        on_hand_cnt: on_hand_cnt
        min_needed: min_needed

    FloatLayout:
        Label:
            text: 'Add Part to Inventory'
            font_size: '25sp'
            size_hint: (1, 0.17)
            pos_hint: {'x': 0, 'y': 0.86}

        GridLayout:
            cols:2
            padding: [50, 100, 50, 120]
            spacing: 5

            ItemLabel:
                text: "Name of Part: "

            TextInput:
                id: part_name
                halign: 'left'
                valign: 'middle'
                multinline:False

            ItemLabel:
                text: "Serial Number: "

            TextInput:
                id: serial_number
                halign: 'left'
                valign: 'middle'
                multiline:False

            ItemLabel:
                text: "How Many On Hand?: "

            TextInput:
                id: on_hand_cnt
                halign: 'left'
                valign: 'middle'
                multinline:False

            ItemLabel:
                text: "Minimum Needed?: "

            TextInput:
                id: min_needed
                halign: 'left'
                valign: 'middle'
                multiline:False

        GridLayout:
            cols:2
            size_hint: 1, 0.15
            padding: [10, 0, 10, 10]

            Button:
                text:"Cancel"
                on_release:
                    app.root.current = "inv_window"
                    root.manager.transition.direction = "left"

            #Here is the button I'm referring to, I realize that putting "root." in front of new_part() is not 
            #the correct thing to put, so it's a placeholder for now:
            
            Button:
                text:"Submit"
                on_release:
                    root.new_part()
                    app.root.current = "inv_window"
                    root.manager.transition.direction = "left"

下面是添加部分屏幕的屏幕截图

在四个字段中输入并单击Submit按钮时所遇到的当前错误如下:

代码语言:javascript
复制
File "C:\Users\edr27\kivy_venv\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
     self.dispatch('on_release')
   File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
   File "C:\Users\edr27\kivy_venv\lib\site-packages\kivy\lang\builder.py", line 57, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "C:\Users\edr27\PycharmProjects\pythonProject\inventory.kv", line 345, in <module>
     root.new_part()
   File "C:\Users\edr27\PycharmProjects\pythonProject\main.py", line 35, in new_part
     np = [self.part_name.text, self.serial_number.text, self.on_hand_cnt.text, self.min_needed.text]
 AttributeError: 'NoneType' object has no attribute 'text'

编辑:

下面是我如何实现Oussama的答案,为了使它工作起来,我所要做的就是更新AddPartWindow类:

代码语言:javascript
复制
class AddPartWindow(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.np = []

    def submit(self):
        self.part_name = self.ids.part_name.text
        self.serial_number = self.ids.serial_number.text
        self.on_hand_cnt = self.ids.on_hand_cnt.text
        self.min_needed = self.ids.min_needed.text

        self.np = [self.part_name, self.serial_number, self.on_hand_cnt, self.min_needed]
        iQue_sheet.append_row(self.np)

我还做了此更改,以便将其附加到工作簿的第3页,而不是第1页:

代码语言:javascript
复制
iQue_sheet = client.open("InventoryBackend").get_worksheet(2)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-01 01:39:40

这个main.py可以自由地导入您需要的东西。这是一个简单的例子,说明你想要做什么,

代码语言:javascript
复制
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.app import App
Builder.load_file('the.kv')

class fscreen(widget):
    def __init__(self, **kwargs):
        supper().__init__(**kwargs)
        self.np = []        

    def submit(self):
            
        self.part_name = self.ids.Pname.text
        self.serial_number = self.ids.Snumber.text
        self.on_hand_cnt = self.ids.onhabdcnt.text
        self.min_needed = self.ids.minneeded.text

        self.np = [self.part_name, self.serial_number, self.on_hand_cnt, self.min_needed]
        iQue_sheet.append(self.np)


class secscreen(widget):
    def __init__(self, **kwargs):
        supper().__init__(**kwargs)
        pass

class thscreen(widget):
    def __init__(self, **kwargs):
        supper().__init__(**kwargs)
        pass

class theapp(App):
    def build(self):
        self.screenm = ScreenManager()
        self.screen = Screen(name = "first screen")
        screen.add_widget(self.fscreen)
        self.screenm.add_widget(screen)
if __name__ = "__main__":
    theapp.run()

这是the.kv文件

代码语言:javascript
复制
<fscreen>
    TextInput:
        id: Pname
        hint_text: 'partname'

    TextInput:
        id: Snumber
        hint_text: 'serialnumber'

    TextInput:
        id: onhandcnt
        hint_text: 'on hand cnt'

    TextInput:
        id: minneeded
        hint_text: 'min nedded' 

    Button:
        text: 'Submit'
        on_press: root.submit()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66897185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档