Closed lymadalin closed 2 years ago
@lymadalin, hi, please provide a reproducible example. I'm not able to replicate this error.
If you want to delete "all" rows of the table, then you would use table.delete_rows()
Isarel-dryer:
您好!首先为您开发出这么好用的组件而向您表示市衷心的感谢!
我的英语不太好,请原谅我用汉语向您表述我的问题。
我是在一个实现增加、删除、修改、查询数据库记录的窗口中,当点击“删除”按钮时,会删除当前的一条记录,同时数据库也会删除这条记录。一般情况下这没有什么问题,但如果我连续删除当前记录,表格中没有记录的时候,再从数据库中提取数据加载到表格时,会出现以下面的错误:
Exception in Tkinter callback Traceback (most recent call last): File "c:\users\madal\appdata\local\programs\python\python38\lib\tkinter__init.py", line 1892, in call__ return self.func(*args) File "d:\projects\yyzn_da2\pages\list_page.py", line 121, in add_item self.refresh_data() File "d:\projects\yyzn_da2\pages\list_page.py", line 94, in refresh_data self.dt.load_table_data() File "C:\Users\madal.virtualenvs\yyzn_da2-0Jfvkwqv\lib\site-packages\ttkbootstrap\tableview.py", line 1042, in load_table_data self.unload_table_data() File "C:\Users\madal.virtualenvs\yyzn_da2-0Jfvkwqv\lib\site-packages\ttkbootstrap\tableview.py", line 1024, in unload_table_data row.hide() File "C:\Users\madal.virtualenvs\yyzn_da2-0Jfvkwqv\lib\site-packages\ttkbootstrap\tableview.py", line 331, in hide self.view.detach(self.iid) File "c:\users\madal\appdata\local\programs\python\python38\lib\tkinter\ttk.py", line 1255, in detach self.tk.call(self._w, "detach", items) _tkinter.TclError: Item I001 not found
删除数据的代码如下:
def delete_item(self):
selected = self.dt.view.selection()
if len(selected) == 0:
return # nothing is selected
row_iid = selected[0]
id = self.dt.get_row(iid=row_iid).values[0]
confirm= Alert.okcancel(
f'是否删除当前选中的项目?',
title='删除确认',
parent=self
)
if confirm == '取消':return
try:
self.data_service.delete(id)
self.dt.delete_row(iid=row_iid)
self.dt.load_table_data()
except Exception as ex:
Alert.show_error_toast(f"删除错误:{ex}")
刷新数据的代码如下:
def refresh_data(self):
rowdata=self.data_service.get_data_by_keyword(self.keyword_var.get())
self.dt.insert_rows(0,rowdata=rowdata)
self.dt.load_table_data()
后来我找到了一个变通的解决方法,就是在
self.dt.load_table_data()
后面加上:
if len(self.dt.get_rows())==0:
self.dt._viewdata.clear()
这样在刷新数据的时候就不会出现上述错误。其中的原因我还无法找到,但我想也许和组件内部的数据刷新不同步有关?
为了方便您查看,我把代码文件放在附件中。请您参考。
再次向您表示感谢!!
从 Windows 版邮件https://go.microsoft.com/fwlink/?LinkId=550986发送
发件人: Israel Dryer @.> 发送时间: Sunday, May 1, 2022 9:58:32 AM 收件人: israel-dryer/ttkbootstrap @.> 抄送: madalin @.>; Mention @.> 主题: Re: [israel-dryer/ttkbootstrap] TableView delete_row() raise Error (Issue #248)
@lymadalinhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Flymadalin&data=05%7C01%7C%7C43f6cf2d05e74886fe6f08da2b161889%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637869671158500863%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=lCiHA7jP0kvMvnDoafhgQgwIXGuDL8m8XelHpd2PNBQ%3D&reserved=0, hi, please provide a reproducible example. I'm not able to replicate this error.
If you want to delete "all" rows of the table, then you would use table.delete_rows()
― Reply to this email directly, view it on GitHubhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fisrael-dryer%2Fttkbootstrap%2Fissues%2F248%23issuecomment-1114099112&data=05%7C01%7C%7C43f6cf2d05e74886fe6f08da2b161889%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637869671158657088%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=mpt5uid8ITsyq%2FkXu1RBxY015qeRK%2FwULIip6u%2FWz6M%3D&reserved=0, or unsubscribehttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABIKSFZI3FU5QSD5DSG3SJLVHXQMRANCNFSM5TB2WWKA&data=05%7C01%7C%7C43f6cf2d05e74886fe6f08da2b161889%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637869671158657088%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=WmXx%2FTrg8ZpAx55%2BPEXePJ%2F8kK69q2fjkr8OAgGGDZ0%3D&reserved=0. You are receiving this because you were mentioned.Message ID: @.***>
@lymadalin, I think I found the issue here:
if record.self._sort == index:
it should be
if record._sort == index:
I'm going to push this fix, and then let me know if this fixes your issue.
@israel-dryer
Thank you, but I'm sorry. This does not solve the problem. But,I think I found the issue here:
because:
if len(self.tablerows) == 0:
return
If the table already has no rows, this code has no chance to execute:
self.unload_table_data()
but the collection self.tablerows_visible
still includes an unpurgeed record.
When you call `load_table_data()' again , the code will raise exception:
for row in self.tablerows_visible:
row.hide()
I tried it and it solved my problem. Can you give it a try?
ttkbootstrap==1.7.6
从 Windows 版邮件https://go.microsoft.com/fwlink/?LinkId=550986发送
发件人: Israel @.> 发送时间: 2022年5月24日 19:31 收件人: @.> 抄送: @.>; @.> 主题: Re: [israel-dryer/ttkbootstrap] TableView delete_row() raise Error (Issue #248)
What version of ttkbootstrap are you running?
― Reply to this email directly, view it on GitHubhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fisrael-dryer%2Fttkbootstrap%2Fissues%2F248%23issuecomment-1135796364&data=05%7C01%7C%7Ca9428ef3b0ae4888e01808da3d78f1e1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637889886909518584%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=SxpO%2B1oxdNe%2BVgTKNrFrxVzDf886fo3HseM9Uu8I1ds%3D&reserved=0, or unsubscribehttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABIKSF47SBRYS6V6K3W3V33VLS4ZBANCNFSM5TB2WWKA&data=05%7C01%7C%7Ca9428ef3b0ae4888e01808da3d78f1e1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637889886909518584%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=MmcZhkmnpXXMuVpRG3kwv4jXYcymXg4LfAXsjvrdJD8%3D&reserved=0. You are receiving this because you were mentioned.Message ID: @.***>
@lymadalin, I'm trying to recreate your issue so that I can test it. Can you please modify the code below so that it creates the issue you are talking about? Otherwise, I only have snippets to look at above to try to guess how you are using the api. Thanks!
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.tableview import Tableview
app = ttk.Window()
columns = ['First Name', 'Last Name', 'Email']
data = [
('John', 'Doe', 'john.doe@gmail.com'),
('Jane', 'Doe', 'jane.doe@yahoo.com')
]
new_data = [('Jax', 'Doe', 'jax.doe@gmail.com')]
table = Tableview(app, coldata=columns, rowdata=data)
table.pack()
rows = table.get_rows()
table.delete_row(iid=rows[0].iid)
table.insert_row(END, ('Jimmy', 'Doe', 'jimmy.doe@aol.com'))
table.load_table_data()
def delete_item():
selected = table.view.selection()
if len(selected) == 0:
return
row_iid = selected[0]
row = table.get_row(iid=row_iid).values[0]
table.delete_row(iid=row.iid)
def refresh_data():
rowdata = new_data
table.insert_rows(0, rowdata=rowdata)
table.load_table_data()
# call the refresh command 2 seconds after starting application
app.after(2000, refresh_data)
app.mainloop()
@israel-dryer Run the following code and click on the "Test" button then you will get an exception
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.tableview import Tableview
app = ttk.Window()
columns = ['First Name', 'Last Name', 'Email']
data = [
('John', 'Doe', 'john.doe@gmail.com'),
('Jane', 'Doe', 'jane.doe@yahoo.com')
]
new_data = [('Jax', 'Doe', 'jax.doe@gmail.com')]
frame_top = ttk.Frame(app)
frame_top.pack()
table = Tableview(app, coldata=columns, rowdata=data)
table.pack()
rows = table.get_rows()
table.delete_row(iid=rows[0].iid)
table.insert_row(END, ('Jimmy', 'Doe', 'jimmy.doe@aol.com'))
table.load_table_data()
def delete_item():
for each in table.view.get_children():
print(each)
table.delete_row(iid=each)
refresh_data()
ttk.Button(frame_top,text='test',command=delete_item).pack()
def refresh_data():
rowdata = new_data
table.insert_rows(0, rowdata=rowdata)
table.load_table_data()
# call the refresh command 2 seconds after starting application
# app.after(2000, refresh_data)
app.mainloop()
@lymadalin, I see... I've actually set up a method for this. The get_rows()
returns a list of TableRow objects that you can work with. This is the recommended method of dealing with the rows instead of grabbing from the internal tk methods.
https://ttkbootstrap.readthedocs.io/en/latest/api/tableview/tableview/#ttkbootstrap.tableview.Tableview.get_rows
https://ttkbootstrap.readthedocs.io/en/latest/api/tableview/tablerow/
You can also use table.delete_rows()
.. if you don't pass any arguments, then all rows will be deleted. https://ttkbootstrap.readthedocs.io/en/latest/api/tableview/tableview/#ttkbootstrap.tableview.Tableview.delete_rows
def delete_item():
for each in table.get_rows():
each.delete()
refresh_data()
OK,Thank you. But but my requirements is that user select row from GUI and removed it, so I had to get the checks from the Treeview. In the special case, the user select and delete the last row of records, so this problem arises... Can this component get the currently selected item?
The content I sent is from Bing translation, if there is an expression error, please forgive me.
从 Windows 版邮件https://go.microsoft.com/fwlink/?LinkId=550986发送
发件人: Israel Dryer @.> 发送时间: Thursday, May 26, 2022 6:01:26 AM 收件人: israel-dryer/ttkbootstrap @.> 抄送: madalin @.>; Mention @.> 主题: Re: [israel-dryer/ttkbootstrap] TableView delete_row() raise Error (Issue #248)
@lymadalinhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Flymadalin&data=05%7C01%7C%7C971df4b04bd74a4ad7e608da3e9a1e34%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891128917365422%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=iA4KAyj0CFqCIuoOKsshlTd7Y4qbTnOm9ge9pp2g8wc%3D&reserved=0, I see... I've actually set up a method for this. The get_rows() returns a list of TableRow objects that you can work with. This is the recommended method of dealing with the rows instead of grabbing from the internal tk methods. https://ttkbootstrap.readthedocs.io/en/latest/api/tableview/tableview/#ttkbootstrap.tableview.Tableview.get_rowshttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fttkbootstrap.readthedocs.io%2Fen%2Flatest%2Fapi%2Ftableview%2Ftableview%2F%23ttkbootstrap.tableview.Tableview.get_rows&data=05%7C01%7C%7C971df4b04bd74a4ad7e608da3e9a1e34%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891128917365422%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hvKstTusPodOd8%2FDXygGQ6pItQz9FIFcXkUaipZWfLY%3D&reserved=0 https://ttkbootstrap.readthedocs.io/en/latest/api/tableview/tablerow/https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fttkbootstrap.readthedocs.io%2Fen%2Flatest%2Fapi%2Ftableview%2Ftablerow%2F&data=05%7C01%7C%7C971df4b04bd74a4ad7e608da3e9a1e34%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891128917365422%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Ld0mGf7hvmOPhQ34D1k64D7VxKi0UNxiptXdf%2FhngiE%3D&reserved=0
You can also use table.delete_rows().. if you don't pass any arguments, then all rows will be deleted. https://ttkbootstrap.readthedocs.io/en/latest/api/tableview/tableview/#ttkbootstrap.tableview.Tableview.delete_rowshttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fttkbootstrap.readthedocs.io%2Fen%2Flatest%2Fapi%2Ftableview%2Ftableview%2F%23ttkbootstrap.tableview.Tableview.delete_rows&data=05%7C01%7C%7C971df4b04bd74a4ad7e608da3e9a1e34%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891128917365422%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=eC6NpGMnvgmNoZHtlDG2QkMOl7JexY6XAC4%2BXW3B3a0%3D&reserved=0
def delete_item(): for each in table.get_rows(): each.delete()
refresh_data()
― Reply to this email directly, view it on GitHubhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fisrael-dryer%2Fttkbootstrap%2Fissues%2F248%23issuecomment-1137886355&data=05%7C01%7C%7C971df4b04bd74a4ad7e608da3e9a1e34%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891128917521636%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=DnR480UipgoL2iWkDAQhVkZCWz2ZZN9EwhedkxBicTA%3D&reserved=0, or unsubscribehttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABIKSF7AKGYF732IDO7SD73VL2PLNANCNFSM5TB2WWKA&data=05%7C01%7C%7C971df4b04bd74a4ad7e608da3e9a1e34%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891128917521636%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=T7x84x%2FZKIfeHwlKYf%2FRgKoZCSDa%2BgpSWxllbq9qI8E%3D&reserved=0. You are receiving this because you were mentioned.Message ID: @.***>
If you right click the row there is a menu option to delete it. Is this what you are looking for?
It is OK,but we need select from the treeview too…
发自我的iPad
在 2022年5月26日,13:12,Israel Dryer @.***> 写道:
If you right click the row there is a menu option to delete it. Is this what you are looking for?
— Reply to this email directly, view it on GitHubhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fisrael-dryer%2Fttkbootstrap%2Fissues%2F248%23issuecomment-1138160510&data=05%7C01%7C%7Cc0f059faed974f1b5bbb08da3ed64cd9%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891387394794870%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=nRzCMjhLc%2BqH94YV1JeTSjJgGLrs7FBgQqtXC8SFc0A%3D&reserved=0, or unsubscribehttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABIKSFZ5SF22QCGCBYNN5X3VL4B27ANCNFSM5TB2WWKA&data=05%7C01%7C%7Cc0f059faed974f1b5bbb08da3ed64cd9%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637891387394794870%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=b5L6kVZ4TDy6jo4CK58mJm%2BWI%2FRyOqHU%2Fzb%2FvAEVbZI%3D&reserved=0. You are receiving this because you were mentioned.Message ID: @.***>
What are you trying to get from the tree view that you can't get from the Tableview API?
The reason that you can't directly modify the Treeview in many cases is that the widget is no longer just a Treeview. There is additional functionality that tracks and manages the records, so bypassing that and deleting directly from the Treeview is what is causing problems.
Is there is something that you need from Treeview, let me know. It may be that it already exists.
Thanks for your patient reply, all I need is a way to get the currently selected row. Since the component didn't provide get_row()
method, I went to The Treeview to get and deleted it.
Thanks for your patient reply, all I need is a way to get the currently selected row. Since the component didn't provide
get_row()
method, I went to The Treeview to get and deleted it.
Ok. If you want to get the currently selected row id's you can use the method table.view.selection()
. This is a method on the underlying Treeview widget. From there you can get the row object by looking it up with table.get_row(iid='I1234')
and then perform the operations you want on the row object.
This gives me an idea though... I have a method called table.get_rows()
that has a few flags for selecting rows in various states, but selected
is not currently one of the options. This is something that I can add in the next version.... something like this would give you the selected row objects... table.get_rows(selected=True)
I tested the solution and it seems to work... table.get_rows(selected=True)
returns a list of tablerow objects that are selected.
This would be something that is fairly easy to add to the currently api.
It would be great if this could be achieved. I'm looking forward to it!
从 Windows 版邮件https://go.microsoft.com/fwlink/?LinkId=550986发送
发件人: Israel @.> 发送时间: 2022年5月31日 11:04 收件人: @.> 抄送: @.>; @.> 主题: Re: [israel-dryer/ttkbootstrap] TableView delete_row() raise Error (Issue #248)
Thanks for your patient reply, all I need is a way to get the currently selected row. Since the component didn't provide get_row() method, I went to The Treeview to get and deleted it.
Ok. If you want to get the currently selected row id's you can use the method table.view.selected. This is a method on the underlying Treeview widget. From there you can get the row object by looking it up with table.get_row(iid='I1234') and then perform the operations you want on the row object.
This gives me an idea though... I have a method called table.get_rows that has a few flags for selecting rows in various states, but selected is not currently one of the options. This is something that I can add in the next version.... something like this would give you the selected row objects... table.get_rows(selected=True)
― Reply to this email directly, view it on GitHubhttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fisrael-dryer%2Fttkbootstrap%2Fissues%2F248%23issuecomment-1141620631&data=05%7C01%7C%7C38409b732ddf498fb7e108da42b240e9%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637895630623626691%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=XbFn8dWhtpbJBUai9%2Bar2YNtjSsYhbmDFs4Oah4mgHQ%3D&reserved=0, or unsubscribehttps://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABIKSF4W4LTB52ZLL74SYJLVMV6TDANCNFSM5TB2WWKA&data=05%7C01%7C%7C38409b732ddf498fb7e108da42b240e9%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637895630623626691%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=a%2F4%2F21fkN0hlArDaK%2Bxw60wTlHG%2B7uY8VWd%2FH5XAEZg%3D&reserved=0. You are receiving this because you were mentioned.Message ID: @.***>
Ok, this feature has been added in 1.8.0 and is now available on PyPi.
Desktop (please complete the following information):
Version:1.7.4 OS:Win10
Describe the bug
When I use delete_row() to delete all record of table,and use insert_row,then raise error "item 1001 not found”。
delete:
dt.delete_row(iid=row_iid)
dt.load_table_data()
add:
insert_row(……) # raise error
To Reproduce
No response
Expected behavior
No response
Screenshots
No response
Additional context
No response