I am new to python and kivy.
I am trying to get value of dynamic row.But now i am getting value like this
Column2
Column1
Can someone tell me how to get value like this ?
1,column1,column2
2,column1,column2
Because i have three column in my database table like id,name,value and i want to insert value in database table through loop
I am using this code
def insert_value(self):
values = []
rows = self.ids.rows
for row in reversed(rows.children):
for ch in row.children:
if isinstance(ch, TextInput):
values.append(ch.text)
lenArray = len(values)
for x in range(0, lenArray):
print (values[x])
demo.py
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.uix.textinput import TextInput
Window.size = (450, 525)
class display(Screen):
def add_more(self):
self.ids.rows.add_row()
def insert_value(self):
values = []
rows = self.ids.rows
for row in reversed(rows.children):
for ch in row.children:
if isinstance(ch, TextInput):
values.append(ch.text)
lenArray = len(values)
for x in range(0, lenArray):
print (values[x])
class Row(BoxLayout):
button_text = StringProperty("")
id = ObjectProperty(None)
class Rows(BoxLayout):
orientation = "vertical"
row_count = 0
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
self.add_row()
def add_row(self):
self.row_count += 1
self.add_widget(Row(button_text=str(self.row_count),id=str("test"+str(self.row_count))))
class test(App):
def build(self):
self.root = Builder.load_file('demo.kv')
return self.root
if __name__ == '__main__':
test().run()
demo.kv
<Row>:
orientation: "horizontal"
spacing: 0, 5
Button:
text: root.button_text
size_hint_x: .2
TextInput:
text:"Column1"
size_hint_x: .8
TextInput:
text:"Column2"
size_hint_x: .8
display:
BoxLayout:
orientation: "vertical"
padding : 20, 20
BoxLayout:
orientation: "horizontal"
Button:
size_hint_x: .2
text: "+Add More"
valign: 'bottom'
on_press: root.add_more()
BoxLayout:
orientation: "horizontal"
Label:
size_hint_x: .2
text: "SN"
valign: 'bottom'
Label:
size_hint_x: .8
text: "Value"
valign: 'bottom'
Rows:
id: rows
BoxLayout:
orientation: "horizontal"
padding : 10, 0
spacing: 10, 10
size_hint: .5, .7
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
on_release:
root.insert_value()
Button:
text: 'Cancel'
on_release: root.dismiss()
To maintain a structure we must create a list of lists, then in each list the first parameter is the text of the Button that we filter through isinstance(), and the other elements are concatenated.
[...]
from kivy.uix.button import Button
class display(Screen):
def add_more(self):
self.ids.rows.add_row()
def insert_value(self):
values = []
rows = self.ids.rows
for row in reversed(rows.children):
vals = []
for ch in reversed(row.children):
if isinstance(ch, TextInput):
vals.append(ch.text)
if isinstance(ch, Button):
vals.insert(0, ch.text)
values.append(vals)
for val in values:
print("{},{},{}".format(*val))
[...]
One option is to add a ListProperty to your Row class that stores the values of the row in the order you want, which makes it easier to obtain them later.
You can use a ListView to show the rows.
Demo.kv:
<Row>:
values: row_id.text, col1.text, col2.text
orientation: "horizontal"
spacing: 0, 5
size_hint_y: None
height: 30
Button:
id: row_id
text: root.button_text
size_hint_x: .2
TextInput:
id: col1
text:"Column1"
size_hint_x: .8
TextInput:
id: col2
text:"Column2"
size_hint_x: .8
<Rows>:
content: content
BoxLayout:
id: content
orientation: "vertical"
size_hint_y: None
height: self.minimum_height
Display:
rows: rows
BoxLayout:
orientation: "vertical"
padding : 20, 20
BoxLayout:
orientation: "horizontal"
Button:
size_hint_x: .2
text: "+Add More"
valign: 'bottom'
on_press: root.add_more()
BoxLayout:
orientation: "horizontal"
Label:
size_hint_x: .2
text: "SN"
valign: 'bottom'
Label:
size_hint_x: .8
text: "Value"
valign: 'bottom'
Rows:
id: rows
BoxLayout:
orientation: "horizontal"
padding : 10, 10
spacing: 10, 10
size_hint: .5, .7
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
on_release:
root.insert_value()
Button:
text: 'Cancel'
on_release: root.dismiss()
Demo.py:
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty, StringProperty, ObjectProperty
from kivy.uix.scrollview import ScrollView
from kivy.clock import Clock
Window.size = (450, 525)
class Display(Screen):
rows = ObjectProperty(None)
def __init__(self, **kwargs):
super(Display, self).__init__(**kwargs)
def add_more(self):
self.rows.add_row()
def insert_value(self):
values = [row.values for row in reversed(self.rows.content.children)]
for row in values:
print(row)
class Row(BoxLayout):
button_text = StringProperty("")
id = ObjectProperty(None)
values = ListProperty()
class Rows(ScrollView):
row_count = 0
content = ObjectProperty(None)
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
Clock.schedule_once(self.add_row)
def add_row(self, *args):
self.row_count += 1
self.content.add_widget(Row(button_text=str(self.row_count),
id="test" + str(self.row_count)))
class Test(App):
def build(self):
self.root = Builder.load_file('Demo.kv')
return self.root
if __name__ == '__main__':
Test().run()
Related
In one part of my program I have a RecycleView that uses a RecycleBoxLayout and together they hold a bunch of DownloadItem instances which itself inherits from MDCard.
The problem with the recycleview is that it sorts the items in an absurd way. I would like the items to be shown in the order that they were added, not be sorted by the recycleview.
Example:
RecycleView sorting items
My Python file:
from kivy.lang import Builder
from kivy.properties import StringProperty, ColorProperty
from kivy.animation import Animation
from kivymd.uix.card import MDCard
from kivymd.app import MDApp
class DownloadItem(MDCard):
path = StringProperty()
url_type = StringProperty("file")
def __init__(self, **kwargs):
self.paused = False
self.fill_animation = None
super(DownloadItem, self).__init__(**kwargs)
def pause_resume_download(self):
if not self.paused:
self.ids.pause_resume_button.icon = "play"
if self.fill_animation is not None:
self.fill_animation.cancel(self.ids.progress_bar)
self.paused = True
else:
self.ids.pause_resume_button.icon = "pause"
self.fill_animation = Animation(value=100, duration=4)
self.fill_animation.bind(on_complete=lambda *args: Animation(color=self.theme_cls.accent_color,
duration=Example.color_duration)
.start(self.ids.progress_bar))
self.fill_animation.start(self.ids.progress_bar)
self.paused = False
Animation(color=app.pause_color if self.paused else self.theme_cls.primary_color,
duration=Example.color_duration).start(self.ids.progress_bar)
def cancel_download(self):
if self.fill_animation is not None:
self.fill_animation.cancel(self.ids.progress_bar)
Animation(color=app.fail_color,
duration=Example.color_duration).start(self.ids.progress_bar)
class Example(MDApp):
fail_color = ColorProperty([255 / 255, 99 / 255, 71 / 255, 1.0])
pause_color = ColorProperty([240 / 255, 163 / 255, 10 / 255, 1.0])
success_color = ColorProperty(None)
color_duration = .15
def __init__(self, **kwargs):
global app
super(Example, self).__init__(**kwargs)
self.kv = Builder.load_file("design.kv")
self.path = "C:/Users/Family/Downloads/"
app = self
def build(self):
self.theme_cls.theme_style = "Dark"
return self.kv
def add_item(self):
self.kv.ids.downloads_list.data.append({"path": self.path + '/' if self.path[-1] != '/' else self.path,
"url_type": "file"})
if __name__ == '__main__':
Example().run()
My KV file:
#:kivy 2.0.0
<TooltipMDLabel#MDLabel+MDTooltip>
<DownloadItem>:
orientation: "vertical"
padding: 10
spacing: 10
size_hint_y: None
height: 100
elevation: 20
border_radius: 5
radius: [5]
MDBoxLayout:
adaptive_height: True
spacing: 5
MDIcon:
icon: root.url_type
size_hint_x: None
width: self.texture_size[0]
TooltipMDLabel:
text: root.path if len(root.path) <= 30 else root.path[:31] + " ..."
tooltip_text: f"Path: {root.path}\nType: {root.url_type}"
tooltip_bg_color: app.theme_cls.bg_darkest
tooltip_text_color: app.theme_cls.opposite_bg_darkest
size_hint_y: None
height: self.texture_size[1]
MDSeparator:
MDBoxLayout:
spacing: 10
MDProgressBar:
id: progress_bar
min: 0
max: 100
value: 50
color: app.theme_cls.primary_color
MDIconButton:
id: pause_resume_button
icon: "pause"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: root.pause_resume_download()
MDIconButton:
icon: "close"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: root.cancel_download()
BoxLayout:
orientation: "vertical"
spacing: 10
RecycleView:
id: downloads_list
viewclass: "DownloadItem"
RecycleBoxLayout:
default_size: None, 100
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: "vertical"
padding: 15
spacing: 15
MDRaisedButton:
text: "Add"
size_hint_x: 1
on_release: app.add_item()
The RecycleView does not sort the items. They are presented in the order that they appear in the data. What you are seeing is the "recycle" behavior, where your DownloadItems are recycled, making it appear that they are sorted. Try adding a count number to the display of each DownloadItem, and you will see more clearly what is happening.
I have used KivyMD to develop a Screen which displays the Parameter values (In a DialogBox) of specific Item (which I listed them as OnelinelistItem). I also want to make provision for the user to change the parameter values from the DialogBox. But apparently I cant update the parameter settings from the DialogBox. The DialogBox contains the Textfield. Can anyone help me to figure out the issue, by going through the code, and let me know, where I am doing it wrong?
TIA! :)
testingsetpointpage.py
'''
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'systemanddock')
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen
from kivymd.uix.dialog import MDDialog
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivymd.uix.button import MDFlatButton
from kivy.properties import StringProperty
Window.size = (1024, 600)
The Builder is shown here:
KV = """
#:kivy 1.11.0
#:import MDDropdownMenu kivymd.uix.menu.MDDropdownMenu
#:import MDRaisedButton kivymd.uix.button.MDRaisedButton
ScreenManager:
MainScreen:
<MainScreen>:
name: 'mainscreen'
NavigationLayout:
ScreenManager:
Screen:
name: 'homemain'
BoxLayout:
orientation:"vertical"
halign:"center"
#DOWN TAB
MDBottomNavigation:
MDBottomNavigationItem:
name: 'setpoint'
text: 'Setpoints'
icon: 'network'
BoxLayout:
orientation: "vertical"
MDToolbar:
title: 'Setpoints'
pos_hint: {'center_x':0.5,'center_y':0.95}
right_action_items: [["wifi", lambda x: app.navigation_draw()]]
left_action_items: [["menu", lambda x: nav_drawer.toggle_nav_drawer()]]
elevation: 10
BoxLayout:
orientation:"vertical"
padding: 5
spacing: 5
MDLabel:
text: " Functions: "
halign:"left"
theme_text_color: "Custom"
text_color: 0, 0, 1, 1
size_hint_y: 0.15
canvas.before:
Color:
rgba: (211/255.0,211/255.0,211/255.0,1)
Rectangle:
size: self.size
pos: self.pos
SetpointContent:
#MAKE THE PARAMETER LIST
<SetpointContent>:
BoxLayout:
orientation: "vertical"
padding: 5
spacing: 5
ScrollView:
MDList:
OneLineListItem:
text: "51P: Phase Time Overcurrent"
on_press: root.show_51Pdata()
<Content51P>
alarmpick51p: alp51p
alarmdelay51p: ald51p
trippick51p: trp51p
invcurve51p: inp51p
orientation: "vertical"
size_hint_y: None
height: "200dp"
GridLayout:
rows: 4
cols: 2
spacing: 10
MDLabel:
text: "Alarm Pickup: "
halign: "center"
theme_text_color: "Custom"
text_color: 0, 0, 1, 1
size_hint_y: 0.15
size_hint_x: 0.4
width:100
MDTextFieldRect:
id: alp51p
text: root.text1
multiline: False
MDLabel:
text: "Alarm Delay: "
halign: "center"
theme_text_color: "Custom"
text_color: 0, 0, 1, 1
size_hint_y: 0.15
size_hint_x: 0.4
width:100
MDTextFieldRect:
id: ald51p
text: str(app.Aldelay51P)
multiline: False
MDLabel:
text: "Trip Pickup: "
halign: "center"
theme_text_color: "Custom"
text_color: 0, 0, 1, 1
size_hint_y: 0.15
size_hint_x: 0.4
width:100
MDTextFieldRect:
id: trp51p
text: str(app.Trpick51P)
multiline: False
MDLabel:
text: "Inverse Curve: "
halign: "center"
theme_text_color: "Custom"
text_color: 0, 0, 1, 1
size_hint_y: 0.15
size_hint_x: 0.4
width:100
MDTextFieldRect:
id: inp51p
text: str(app.InverseCurve)
multiline: False
#####
"""
and the Classes are defined here:
class Content51P(BoxLayout):
app=MDApp.get_running_app()
text1 = StringProperty("1")
alarmpick51p = ObjectProperty()
alarmdelay51p = ObjectProperty()
trippick51p = ObjectProperty()
invcurve51p = ObjectProperty()
class MainScreen(Screen):
class SetpointContent(Screen):
def show_51Pdata(self):
self.dialog = MDDialog(title="51P Parameters:",
type="custom",
content_cls=Content51P(),
buttons=[MDFlatButton(text='Close', on_release=self.close_dialog),
MDFlatButton(text='Update', on_release=self.update51P)]
)
self.dialog.auto_dismiss = False
self.dialog.open()
def update51P(self, obj):
duc = Content51P()
app = MDApp.get_running_app()
duc.text1 = duc.ids.alp51p.text
print(duc.text1)
app.Alpick51P = float(duc.text1)
print(app.Alpick51P)
def close_dialog(self, obj):
self.dialog.auto_dismiss = True
self.dialog.dismiss()
class MainApp(MDApp):
Alpick51P = ObjectProperty("5")
Aldelay51P = ObjectProperty("5")
Trpick51P = ObjectProperty("5")
InverseCurve = ObjectProperty("Very Inverse")
def build(self):
self.theme_cls.primary_palette = "Blue"
screen = Builder.load_string(KV)
return screen
def navigation_draw(self):
print("Navigation")
def on_start(self):
pass
if __name__ == '__main__':
MainApp().run()
'''
The outlook looks something like this. I want to update the four parameters as the user clicks on the Update button and be able to view the value, the next time I open the DialogBx.
In the kv rule, under <Content51P> for MDTextFieldRect textinputs add:
on_text: app.Alpick51P = self.text
on_text: app.Aldelay51P = self.text
on_text: app.Trpick51P = self.text
on_text: app.InverseCurve = self.text
The on_text method should go to respective MDTextFieldRect.
Update the update51P() function should be like below now:
def update51P(self, obj):
app = MDApp.get_running_app()
print(app.Alpick51P)
print(app.Aldelay51P)
print(app.Trpick51P)
print(app.InverseCurve)
This would now print the updated inputs from textinput fields.
I try to make a table with data from a SQL DB and images not from a DB. I have tried several things but the image don't show up.
I used this code and modified it: Link to Stackoverflow Code
Code snippets that i Changed in Main.py
import sqlite3
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty
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.uix.image import Image #<<<<<<<<<<<<<<< new
[...]
class RV(BoxLayout):
data_items = ListProperty([])
image = Image(source='image.gif') #<<<<<<<<<<<<<<<<<<< new
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.get_users()
def get_users(self):
connection = sqlite3.connect("demo.db")
cursor = connection.cursor()
cursor.execute("SELECT * FROM Users ORDER BY UserID ASC")
rows = cursor.fetchall()
# create data_items
for row in rows:
for col in row:
self.data_items.append(col)
print(type(col))
self.data_items.append(self.image) #<<<<<<<<<<<<<<<<<<< new
[...]
test.kv
#:kivy 1.10.0
<TextInputPopup>:
title: "Popup"
size_hint: None, None
size: 400, 400
auto_dismiss: False
BoxLayout:
orientation: "vertical"
TextInput:
id: txtinput
text: root.obj_text
Button:
size_hint: 1, 0.2
text: "Save Changes"
on_release:
root.obj.update_changes(txtinput.text)
root.dismiss()
Button:
size_hint: 1, 0.2
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: "User ID"
Label:
text: "User Name"
Label:
text: "Image To Insert"
BoxLayout:
RecycleView:
viewclass: 'SelectableButton'
data: [{'text': str(x)} for x in root.data_items] #<<<<<<<<<< Problem?
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
Problem:
Link that shows a Picture of my problem
Can anyone tell me how to add a date picker or kivy calendar on date TextBox?
I have two file test.py and test.kv file.
test.py
import kivy
import sqlite3 as lite
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.label import Label
Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (400, 125)
class Testing(Screen):
pass
class Testing(App):
def build(self):
self.root = Builder.load_file('test.kv')
return self.root
if __name__ == '__main__':
Testing().run()
test.kv
Testing:
BoxLayout:
orientation: "vertical"
padding : 20, 20
BoxLayout:
orientation: "horizontal"
padding: 10, 10
spacing: 10, 10
size_hint_x: .55
Label:
text: "Date"
text_size: self.size
valign: 'middle'
size_hint_x: .2
TextInput:
size_hint_x: .3
BoxLayout:
orientation: "horizontal"
padding : 10, 0
spacing: 10, 10
size_hint: .5, .7
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
on_release:
root.dismiss()
Button:
text: 'Cancel'
on_release: root.dismiss()
.kv file
#:import MDTextField kivymd.uix.textfield.MDTextField
MDTextField:
id: set_date
hint_text: 'Start Date'
write_tab: False
on_focus: root.setDate()
.py file
from kivymd.uix.picker import MDDatePicker
def setDate(self,dobj):
self.ids.set_date.text = str(dobj)
pass
def fromDate(self):
self.foc = self.ids.set_date.focus
if(self.foc==True):
MDDatePicker(self.setFDate).open()
else:
print("not")
I am trying to make an app that has a stack of rows that you can add to/remove from at the press of buttons.
I have got the 'Add Row' button working well, now I need the 'Remove Row' functionality.
I have the rows in lists '(self.rows.content.children)', I just need to know how to pop the last one from the list, then keep adding/subtracting at will.
Thanks for looking.
test.py
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.properties import ObjectProperty, StringProperty, ListProperty
from kivy.clock import Clock
from sql_update_data import update_db
kivy.require('1.10.1')
class GUILayout(BoxLayout, GridLayout):
rows = ObjectProperty(None)
def add_more(self):
self.ids.rows.add_row()
def remove_row(self):
print("Remove last row")
def insert_value(self):
values = [row.values for row in reversed(self.rows.content.children)]
for category, id, strap in values:
update_db(category, id, strap)
class Row(BoxLayout):
button_text = StringProperty("")
id = ObjectProperty(None)
values = ListProperty()
class Rows(ScrollView):
row_count = 0
content = ObjectProperty(None)
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
Clock.schedule_once(self.add_row)
def add_row(self, *args):
self.row_count += 1
self.content.add_widget(Row(button_text=str(self.row_count),
id=str(self.row_count)))
class TestApp(App):
def build(self):
return GUILayout()
GUIApp = TestApp()
GUIApp.run()
test.kv
#: import main test
<Row>:
values: row_id.text, col1.text, col2.text
orientation: "horizontal"
spacing: 0, 5
size_hint_y: None
height: "60dp"
spacing: 2
pos_hint: {'center_x': .50, 'y': .80}
Button:
id: row_id
text: root.button_text
size_hint_x: .1
Spinner:
id: col1
text: 'Select Category'
values: ['One', 'Two', 'Three']
size_hint_x: .3
TextInput:
id: col2
size_hint_x: .8
<Rows>:
content: content
BoxLayout:
id: content
orientation: "vertical"
size_hint_y: None
height: self.minimum_height
GUILayout:
<GUILayout>:
rows: rows
orientation: "vertical"
padding: 10
spacing: 10
BoxLayout:
orientation: "horizontal"
height: 60
BoxLayout:
orientation: "horizontal"
size_hint_x: .25
TabbedPanel:
do_default_tab: False
# ----------- TAB 1 ------------
TabbedPanelItem:
text: "tab1"
BoxLayout:
orientation: 'vertical'
Rows:
id: rows
GridLayout:
rows: 1
cols: 6
padding: 1
spacing: 5
size_hint_y: None
height: 50
# --------- MINUS ---------
Button:
text: " - "
font_size: 70
size_hint_x: .1
on_press: root.remove_row()
# -------- SUBTRACT -------
Button:
text: " + "
font_size: 50
size_hint_x: .1
on_press: root.add_more()
# ----- UPDATE MAESTRO -----
Button:
text: "Update Maestro"
size_hint_x: .4
on_press: root.insert_value()
# -------- SETTINGS --------
Button:
text: "Settings"
font_size: 30
size_hint_x: .2
What you should do is remove the last child widget from content using the remove_widget method, on the other hand do not use id as the name of a variable since it is a reserved word:
On the other hand GUILayout must not inherit 2 widgets, it is only necessary that it be from BoxLayout.
# ..
class GUILayout(BoxLayout):
rows = ObjectProperty(None)
def add_more(self):
self.rows.add_row()
def remove_row(self):
self.rows.remove_row()
def insert_value(self):
values = [row.values for row in reversed(self.rows.content.children)]
for category, _id, strap in values:
update_db(category, _id, strap)
#...
class Rows(ScrollView):
content = ObjectProperty(None)
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
self.row_count = 0
Clock.schedule_once(lambda _: self.add_row())
def add_row(self):
self.row_count += 1
self.content.add_widget(Row(button_text=str(self.row_count),
id=str(self.row_count)))
def remove_row(self):
if self.content.children:
self.content.remove_widget(self.content.children[0])
self.row_count -= 1
# ...