单击行时如何在弹出框中传递多个参数 [英] how to pass more then one parameter in pop up box when click on row

查看:119
本文介绍了单击行时如何在弹出框中传递多个参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

user.py

import kivy

kivy.require('1.9.0')  # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty,NumericProperty
from kivy.lang import Builder

from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window



Window.size = (500, 500)

#con = lite.connect('fact.db')
#con.text_factory = str
#cur = con.cursor()

class TextInputPopup(Popup):
    obj = ObjectProperty(None)
    obj_text = StringProperty("")

    #print(obj);
    def __init__(self, obj, **kwargs):
        super(TextInputPopup, self).__init__(**kwargs)
        self.obj = obj
        self.obj_text = obj.text

class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                  RecycleGridLayout):
    ''' Adds selection and focus behaviour to the view. '''


class SelectableButton(RecycleDataViewBehavior, Button):
    ''' Add selection support to the Button '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableButton, self).refresh_view_attrs(rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(SelectableButton, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected


    def on_press(self,*args):
        popup = TextInputPopup(self)
        popup.open()

    def update_changes(self):
        self.text = txt


class RV(BoxLayout):
    data_items = ListProperty([])

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.get_users()

    def get_users(self):
        #cur.execute("SELECT * FROM `users` order by id asc")
        #rows = cur.fetchall()
        '''This result retrieve from database'''
        rows = [(1, 'Yash', 'Chopra'),(2, 'amit', 'Kumar')]

        for row in rows:
            for col in row:
                self.data_items.append(col)


class ListUser(App):
    title = "Users"

    def build(self):
        self.root = Builder.load_file('user.kv')
        return RV()



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

user.kv

    #:kivy 1.10.0

<TextInputPopup>:
    title: "Update State"
    size_hint: None, None
    size: 350, 350
    auto_dismiss: False

    BoxLayout:
        orientation: "vertical"
        TextInput:
            id: txtinput
            text: root.obj_text
        Button:
            size_hint: 1, 0.4
            text: "Save Changes"
            on_release:
                root.obj.update_changes(txtinput.text)
                root.dismiss()
        Button:
            size_hint: 1, 0.4
            text: "Cancel Changes"
            on_release: root.dismiss()


<SelectableButton>:
    # Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<RV>:
    BoxLayout:
        orientation: "vertical"

        GridLayout:
            size_hint: 1, None
            size_hint_y: None
            height: 25
            cols: 3

            Label:
                text: "ID"
            Label:
                text: "First Name"
            Label:
                text: "Last Name"

        BoxLayout:
            RecycleView:
                viewclass: 'SelectableButton'
                data: [{'text': str(x)} for x in root.data_items]
                SelectableRecycleGridLayout:
                    cols: 3
                    default_size: None, dp(26)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

现在我的第一个窗口显示为-第一个屏幕

现在我的第二个窗口显示如下-第二个屏幕

但是我想要第二个窗口屏幕-第二个屏幕

我是kivy/python的新手.
我正在从数据库中检索数据并显示在列表中.现在,我单击任何列,然后仅显示自身列值,例如 2 : https://i.stack.imgur .com/Ieiut.jpg.我无法传递三个变量.

我想传递第三个屏幕截图之类的行值 3 : https://i.stack.imgur.com/UIyV5.jpg.但是我不不知道该怎么办?请有人可以建议我该怎么做.

解决方案

请参阅说明和示例以获取详细信息.

单击一行-显示所有列

RecycleView 中的视图是通过处理以下数据生成的:本质上是字典列表.首先,我们将连接到RecycleView的数据.

def apply_selection(self, rv, index, is_selected):
    ''' Respond to the selection of items in the view. '''
    self.selected = is_selected
    self.rv_data = rv.data

其次,当按下行中的任何按钮时,我们将确定行的起点,如下所示.我们将把self传递给Edit类.

def on_press(self):
    self.start_point = 0
    end_point = MAX_TABLE_COLS
    rows = len(self.rv_data) // MAX_TABLE_COLS
    for row in range(rows):
        # check index is in column range
        if self.index in list(range(end_point)):
            break
        self.start_point += MAX_TABLE_COLS
        end_point += MAX_TABLE_COLS

    popup = Edit(self)
    popup.open()

第三,在Edit类(弹出窗口小部件)中,我们将弹出窗口的内容定义为容器(BoxLayout).在BoxLayout中,有一个GridLayout(包含Labels和TextInput)和两个Button(Save和Cancel).我们提取起点和列数据如下:

class Edit(Popup):
    start_point = NumericProperty(0)
    col_data = ListProperty(["?", "?", "?"])

    def __init__(self, obj, **kwargs):
        super(Edit, self).__init__(**kwargs)
        self.start_point = obj.start_point
        self.col_data[0] = obj.rv_data[obj.start_point]["text"]
        self.col_data[1] = obj.rv_data[obj.start_point + 1]["text"]
        self.col_data[2] = obj.rv_data[obj.start_point + 2]["text"]

示例

main.py

import kivy

kivy.require('1.10.0')  # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.lang import Builder

from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window


Window.size = (500, 500)

MAX_TABLE_COLS = 3

con = lite.connect('company.db')
# con.text_factory = str
cur = con.cursor()


class Edit(Popup):
    start_point = NumericProperty(0)
    col_data = ListProperty(["?", "?", "?"])

    def __init__(self, obj, **kwargs):
        super(Edit, self).__init__(**kwargs)
        self.start_point = obj.start_point
        self.col_data[0] = obj.rv_data[obj.start_point]["text"]
        self.col_data[1] = obj.rv_data[obj.start_point + 1]["text"]
        self.col_data[2] = obj.rv_data[obj.start_point + 2]["text"]

    def package_changes(self, fname, lname):
        self.col_data[1] = fname
        self.col_data[2] = lname


class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                  RecycleGridLayout):
    ''' Adds selection and focus behaviour to the view. '''


class SelectableButton(RecycleDataViewBehavior, Button):
    ''' Add selection support to the Button '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)
    rv_data = ObjectProperty(None)
    start_point = NumericProperty(0)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableButton, self).refresh_view_attrs(rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(SelectableButton, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        self.rv_data = rv.data

    def on_press(self):
        self.start_point = 0
        end_point = MAX_TABLE_COLS
        rows = len(self.rv_data) // MAX_TABLE_COLS
        for row in range(rows):
            # check index is in column range
            if self.index in list(range(end_point)):
                break
            self.start_point += MAX_TABLE_COLS
            end_point += MAX_TABLE_COLS

        popup = Edit(self)
        popup.open()


class RV(BoxLayout):
    data_items = ListProperty([])

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.get_users()

    def get_users(self):
        '''This result retrieve from database'''

        cur.execute("SELECT * FROM Users ORDER BY UserID ASC")
        rows = cur.fetchall()

        # create data_items
        for row in rows:
            for col in row:
                self.data_items.append(col)

    def update_changes(self, obj):
        # update data_items
        # obj.start_point + 1 --- skip UserID
        for index in range(obj.start_point + 1, obj.start_point + MAX_TABLE_COLS):
            self.data_items[index] = obj.col_data[index - obj.start_point]

        # update Database Table
        cur.execute("UPDATE Users SET FirstName=?, LastName=? WHERE UserID=?", (obj.col_data[1], obj.col_data[2], obj.col_data[0]))
        con.commit()


class ListUser(App):
    title = "Users"

    def build(self):
        self.root = Builder.load_file('test.kv')
        return RV()


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

test.kv

#:kivy 1.10.0

<Edit>:
    title: "Update State"
    size_hint: None, None
    size: 350, 350
    auto_dismiss: False

    BoxLayout:
        orientation: "vertical"
        GridLayout:
            cols: 2
            Label:
                text: "UserID"
            Label:
                id: userid
                text: root.col_data[0]
            Label:
                text: "First Name"
            TextInput:
                id: fname
                text: root.col_data[1]
            Label:
                text: "Last Name"
            TextInput:
                id: lname
                text: root.col_data[2]
        Button:
            size_hint: 1, 0.4
            text: "Save Changes"
            on_release:
                root.package_changes(fname.text, lname.text)
                app.root.update_changes(root)    # pass obj
                root.dismiss()
        Button:
            size_hint: 1, 0.4
            text: "Cancel Changes"
            on_release: root.dismiss()


<SelectableButton>:
    # Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<RV>:
    BoxLayout:
        orientation: "vertical"

        GridLayout:
            size_hint: 1, None
            size_hint_y: None
            height: 25
            cols: 3

            Label:
                text: "ID"
            Label:
                text: "First Name"
            Label:
                text: "Last Name"

        BoxLayout:
            RecycleView:
                viewclass: 'SelectableButton'
                data: [{'text': str(x)} for x in root.data_items]
                SelectableRecycleGridLayout:
                    cols: 3
                    default_size: None, dp(26)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

输出

user.py

import kivy

kivy.require('1.9.0')  # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty,NumericProperty
from kivy.lang import Builder

from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window



Window.size = (500, 500)

#con = lite.connect('fact.db')
#con.text_factory = str
#cur = con.cursor()

class TextInputPopup(Popup):
    obj = ObjectProperty(None)
    obj_text = StringProperty("")

    #print(obj);
    def __init__(self, obj, **kwargs):
        super(TextInputPopup, self).__init__(**kwargs)
        self.obj = obj
        self.obj_text = obj.text

class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                  RecycleGridLayout):
    ''' Adds selection and focus behaviour to the view. '''


class SelectableButton(RecycleDataViewBehavior, Button):
    ''' Add selection support to the Button '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableButton, self).refresh_view_attrs(rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(SelectableButton, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected


    def on_press(self,*args):
        popup = TextInputPopup(self)
        popup.open()

    def update_changes(self):
        self.text = txt


class RV(BoxLayout):
    data_items = ListProperty([])

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.get_users()

    def get_users(self):
        #cur.execute("SELECT * FROM `users` order by id asc")
        #rows = cur.fetchall()
        '''This result retrieve from database'''
        rows = [(1, 'Yash', 'Chopra'),(2, 'amit', 'Kumar')]

        for row in rows:
            for col in row:
                self.data_items.append(col)


class ListUser(App):
    title = "Users"

    def build(self):
        self.root = Builder.load_file('user.kv')
        return RV()



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

user.kv

    #:kivy 1.10.0

<TextInputPopup>:
    title: "Update State"
    size_hint: None, None
    size: 350, 350
    auto_dismiss: False

    BoxLayout:
        orientation: "vertical"
        TextInput:
            id: txtinput
            text: root.obj_text
        Button:
            size_hint: 1, 0.4
            text: "Save Changes"
            on_release:
                root.obj.update_changes(txtinput.text)
                root.dismiss()
        Button:
            size_hint: 1, 0.4
            text: "Cancel Changes"
            on_release: root.dismiss()


<SelectableButton>:
    # Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<RV>:
    BoxLayout:
        orientation: "vertical"

        GridLayout:
            size_hint: 1, None
            size_hint_y: None
            height: 25
            cols: 3

            Label:
                text: "ID"
            Label:
                text: "First Name"
            Label:
                text: "Last Name"

        BoxLayout:
            RecycleView:
                viewclass: 'SelectableButton'
                data: [{'text': str(x)} for x in root.data_items]
                SelectableRecycleGridLayout:
                    cols: 3
                    default_size: None, dp(26)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

Now my first window showing Like this -First Screen

Now my second window showing Like this - Second Screen

But i want to my second window screen like this -Second Screen

I am new to kivy/python.
I am retrieving data from database and showing in list.Now i am clicking on any column then it shows only self column value like this 2: https://i.stack.imgur.com/Ieiut.jpg.I couldn't pass three variable.

I want to pass row value like third screenshot 3: https://i.stack.imgur.com/UIyV5.jpg.But i don't know how to do?Please anyone can suggest me how do i do this.

解决方案

Please refer to the explanations, and example for details.

Click A Row - Show All Columns

The view in RecycleView is generatad by processing the data which is essentially a list of dicts. Firstly, we will hook up to the RecycleView's data.

def apply_selection(self, rv, index, is_selected):
    ''' Respond to the selection of items in the view. '''
    self.selected = is_selected
    self.rv_data = rv.data

Secondly, we will determine the start point of the row when any button in the row is pressed, as follow. We will pass self to the Edit class.

def on_press(self):
    self.start_point = 0
    end_point = MAX_TABLE_COLS
    rows = len(self.rv_data) // MAX_TABLE_COLS
    for row in range(rows):
        # check index is in column range
        if self.index in list(range(end_point)):
            break
        self.start_point += MAX_TABLE_COLS
        end_point += MAX_TABLE_COLS

    popup = Edit(self)
    popup.open()

Thirdly, in the Edit class (popup widget), we defined the popup's content as a container (BoxLayout). Inside the BoxLayout, there is a GridLayout (containing Labels and TextInput), and two Buttons (Save, and Cancel). We extract the start point and the column data as follow:

class Edit(Popup):
    start_point = NumericProperty(0)
    col_data = ListProperty(["?", "?", "?"])

    def __init__(self, obj, **kwargs):
        super(Edit, self).__init__(**kwargs)
        self.start_point = obj.start_point
        self.col_data[0] = obj.rv_data[obj.start_point]["text"]
        self.col_data[1] = obj.rv_data[obj.start_point + 1]["text"]
        self.col_data[2] = obj.rv_data[obj.start_point + 2]["text"]

Example

main.py

import kivy

kivy.require('1.10.0')  # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.lang import Builder

from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window


Window.size = (500, 500)

MAX_TABLE_COLS = 3

con = lite.connect('company.db')
# con.text_factory = str
cur = con.cursor()


class Edit(Popup):
    start_point = NumericProperty(0)
    col_data = ListProperty(["?", "?", "?"])

    def __init__(self, obj, **kwargs):
        super(Edit, self).__init__(**kwargs)
        self.start_point = obj.start_point
        self.col_data[0] = obj.rv_data[obj.start_point]["text"]
        self.col_data[1] = obj.rv_data[obj.start_point + 1]["text"]
        self.col_data[2] = obj.rv_data[obj.start_point + 2]["text"]

    def package_changes(self, fname, lname):
        self.col_data[1] = fname
        self.col_data[2] = lname


class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                  RecycleGridLayout):
    ''' Adds selection and focus behaviour to the view. '''


class SelectableButton(RecycleDataViewBehavior, Button):
    ''' Add selection support to the Button '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)
    rv_data = ObjectProperty(None)
    start_point = NumericProperty(0)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableButton, self).refresh_view_attrs(rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(SelectableButton, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        self.rv_data = rv.data

    def on_press(self):
        self.start_point = 0
        end_point = MAX_TABLE_COLS
        rows = len(self.rv_data) // MAX_TABLE_COLS
        for row in range(rows):
            # check index is in column range
            if self.index in list(range(end_point)):
                break
            self.start_point += MAX_TABLE_COLS
            end_point += MAX_TABLE_COLS

        popup = Edit(self)
        popup.open()


class RV(BoxLayout):
    data_items = ListProperty([])

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.get_users()

    def get_users(self):
        '''This result retrieve from database'''

        cur.execute("SELECT * FROM Users ORDER BY UserID ASC")
        rows = cur.fetchall()

        # create data_items
        for row in rows:
            for col in row:
                self.data_items.append(col)

    def update_changes(self, obj):
        # update data_items
        # obj.start_point + 1 --- skip UserID
        for index in range(obj.start_point + 1, obj.start_point + MAX_TABLE_COLS):
            self.data_items[index] = obj.col_data[index - obj.start_point]

        # update Database Table
        cur.execute("UPDATE Users SET FirstName=?, LastName=? WHERE UserID=?", (obj.col_data[1], obj.col_data[2], obj.col_data[0]))
        con.commit()


class ListUser(App):
    title = "Users"

    def build(self):
        self.root = Builder.load_file('test.kv')
        return RV()


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

test.kv

#:kivy 1.10.0

<Edit>:
    title: "Update State"
    size_hint: None, None
    size: 350, 350
    auto_dismiss: False

    BoxLayout:
        orientation: "vertical"
        GridLayout:
            cols: 2
            Label:
                text: "UserID"
            Label:
                id: userid
                text: root.col_data[0]
            Label:
                text: "First Name"
            TextInput:
                id: fname
                text: root.col_data[1]
            Label:
                text: "Last Name"
            TextInput:
                id: lname
                text: root.col_data[2]
        Button:
            size_hint: 1, 0.4
            text: "Save Changes"
            on_release:
                root.package_changes(fname.text, lname.text)
                app.root.update_changes(root)    # pass obj
                root.dismiss()
        Button:
            size_hint: 1, 0.4
            text: "Cancel Changes"
            on_release: root.dismiss()


<SelectableButton>:
    # Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<RV>:
    BoxLayout:
        orientation: "vertical"

        GridLayout:
            size_hint: 1, None
            size_hint_y: None
            height: 25
            cols: 3

            Label:
                text: "ID"
            Label:
                text: "First Name"
            Label:
                text: "Last Name"

        BoxLayout:
            RecycleView:
                viewclass: 'SelectableButton'
                data: [{'text': str(x)} for x in root.data_items]
                SelectableRecycleGridLayout:
                    cols: 3
                    default_size: None, dp(26)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

Output

这篇关于单击行时如何在弹出框中传递多个参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆