单击行时如何在弹出框中传递多个参数 [英] how to pass more then one parameter in pop up box when click on row
问题描述
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屋!