⚡ I am an aspiring coder and creator of the Python library tksheet.
🌱 I write Python code and I'm learning web development. 🌳
☕ If you've found my work useful and would like to buy me a coffee you can do so here.
Python tkinter table widget for displaying tabular data
Home Page: https://pypi.org/project/tksheet/
License: MIT License
tksheet/tksheet/_tksheet_main_table.py
Lines 3459 to 3523 in e70ca2a
Good Day,
I am actually using an object as a cell content that has a __str__
defined method.
The problem is when I type a text with \n
, it doesn't display correctly the text.
When I press <Return>
the displayed box has the right height but the text itself is shifted up by few pixels (I would say 5).
But here is the point of this ticket:
When I copy the text to another cell, the box doesn't change its size and the displayed text goes out of the box.
My guess is Line 3467, lns
can only contains one string and is not consistent with L3465 where it's splitted by \n
.
Hence, Line 3492 is always false.
I am a bit struggling facing those two issues, I think both problems are of the same nature, But for Now I have only found the Ctrl_V issue.
I would appreciate your help very much.
Best Regards
tksheet/tksheet/_tksheet_main_table.py
Lines 4212 to 4215 in 17ed5d4
Good Day,
On Excel, <Tab>
key is bound like <Return>+<Right>
. It validates and moves to the next right cell.
I'd like to add it at the creation of the text editor when the edit cell start.
In a more generic way, can we just add the possibility of binding other keys on the text editor?
If it already exists please tell me how to do such.
Best Regards
Hi!
tksheet/tksheet/_tksheet_main_table.py
Lines 4451 to 4465 in b4503b9
I am suggesting here, now that we have the option to disable the cell auto resize, to size the text editor to the text itself or the cell dimension.
Something like this:
def create_text_editor(self, r = 0, c = 0, text = None, state = "normal", see = True, set_data_ref_on_destroy = False, binding = None):
self.destroy_text_editor()
if see:
has_redrawn = self.see(r = r, c = c, check_cell_visibility = True)
if not has_redrawn:
self.refresh()
self.text_editor_loc = (r, c)
x = self.col_positions[c]
y = self.row_positions[r]
w = self.col_positions[c + 1] - x + 1
h = self.row_positions[r + 1] - y + 6
if text is None:
text = ""
else:
text_w = self.GetTextWidth(text) + 10
text_h = self.GetTextHeight(text) + 10
if h < text_h:
h = int(text_h)
if w < text_w:
w = int(text_w)
self.hide_current()
self.text_editor = TextEditor(self, text = text, font = self.my_font, state = state, width = w, height = h, border_color = self.table_selected_cells_border_fg, show_border = self.show_selected_cells_border)
It will also help in the case of the user is giving a value from the extra_begin_edit_cell
that could be bigger than the cell.
EDIT: I found that 10 px more is better. It shows the plenty text correctly without wrapping the text.
Good Day,
Me again~
tksheet/tksheet/_tksheet_main_table.py
Lines 540 to 555 in 2c20286
When I copy 1 column and paste it to another one, the empty rows are removed, so it goes up the rows with values on top.
Same when I copy 2 columns.
The line 550 nd.append(r[:len(r) - next(i for i, c in enumerate(reversed(r)) if c)])
that raise the exception StopIteration
. Is it the behavior intended?
Best Regards
When calling highlight_rows
or highlight_cols
they are calling their respective functions in tksheet_main_table. However those don't expect the argument highlight_index
but instead want highlight_header
.
Traceback (most recent call last):
File "$WORKFOLDER/code/fiprotima/src/test_test.py", line 55, in <module>
sheet.highlight_rows()
File "~/.local/share/virtualenvs/fiprotima-B_NhjLga/lib/python3.8/site-packages/tksheet/_tksheet.py", line 1047, in highlight_rows
self.MT.highlight_rows(rows = rows,
TypeError: highlight_rows() got an unexpected keyword argument 'highlight_index'
after editing a cell,
when user clicked on a different cell, the wrong cell gets activated.
(the cell that is under the clicked cell).
Hello,
Is there property that make auto fit cells to content eg. multi line values?
I know it is possible to make autoresize by double click on each cell to fit to content. Is it possible to make same on startup to every cell?
This widget is very nice keep up the good work. I want to use it in a tool I am making. Note I am a newbie to tkinter. Is is possible to call one of my functions when the user say selects row?
Hi, I'm using tksheet
and I really like it, thanks for all the effort you've put into it.
In this application I'm developing, I need the value columns to be right-aligned so that the decimal fields align - it is essential for my users to see the values aligned to avoid mistakes.
I believe tksheet doesn't support right alignment currently, and alignment changes are global. I want to implement right-alignment and only for some select columns, not the entire sheet.
Is this something you plan on implementing? Can I help somehow?
Alternatively, can you give me some code insights and hints on where/how to implement it myself?
Will fix in next couple of days
If an empty cell is selected, the first keystroke goes into switching the cell in edit mode. Would be good if the character could be already entered in the cell after the first keystroke.
Hi,
First, Thank you for this widget I was looking for.
I made some tests with cell editor such combobox with the following example I added in the demo:
self.sheet.create_dropdown(3, 3, values=["AAA","BBB","CCC","DDD"], set_value="CCC", destroy_on_select=False )
The initialization does not work because set_value is not part of combox config, with the following small correction it seems to work
Correction:
line 169 _tksheet_other_classes.py
Remove set_value from the init, set_value is done just below.
ttk.Combobox.__init__(self,
parent,
font = font,
state = state,
values = values,
**#set_value = set_value,**
textvariable = self.displayed)
If it can help, that could be nice to have as well checkbox as cell editor
Thanks again
Hello,
First of all, congratulations for your job. You are doing really well.
I was wondering if there is anyway to make border at cells to be able to make tables.
Regards.
In version <= 4.9.1, scrolling the mouse wheel scrolls the sheet vertically by default, as expected, similar to excel.
But in version 4.9.2 the mouse wheel is now scrolling horizontally by default
I can confirm the issue still exists in the latest version (4.9.4 right now) - it can be reproduced by running the default demo then scrolling your mouse wheel.
First of all, thank you for creating this widget! I'm still a big noob, I just started coding less than 6 months ago and this is just perfect of an appointments app I'm creating for a dentist clinic. The only thing I'd like to know is if I can find documentation about if it's possible to edit the row index because I want to change them from "1","2","3"... to display hours, but doesn't matter what I do, I can't edit it.
Thank you so much and sorry if I'm asking something too stupid.
Hi,
I am pasting a lot of text inside one cell (especially with \n
), and I usually don't need to display it.
There is Three levels in this proposal:
If I have a fixed number of columns, is it possible to expand the columns proportionally when I expand the main window by the x axis? Basically mimicking the tkinter .columnconfigure
method for frames and widgets.
Example:
In this program you can see that the bottom labels expand proportionally but the columns of the tksheet Sheet don't .
Code I used for the bottom frame having the labels:
bottom_frame.columnconfigure(0, weight=1)
for each column of the grid.
Hello,
I was wondering if it would be possible to implement a binding similar to edit_cell, except for when the user starts to edit a cell?
Thank you in advance
Hello, you are doing great in your job, congrats!
I would like to know if can i take my data in excel and display it on tksheet. following my path:
"C:/Users/Marcio Romeiro/Favorites/Desktop/Felipe/Apparatus/CDGN/dados_de_entrada.xls"
Hi, Thanks for your contribute... it's very nice. It helped me a lot.
I have a question, i want to set position, width and height for showtable, i see it in init of sheet, but it doesn't seem to work.. Can you answer for me?
Thank you very much!
self.sheet.font(('Calibri', 9, 'normal'))
raises an error.
Traceback:
Traceback (most recent call last):
File "", line 1, in
runfile('C:/Users/admin/DS/Rugby/API/RLstat.pyw', wdir='C:/Users/admin/DS/Rugby/API')
File "C:\Users\admin\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile
execfile(filename, namespace)
File "C:\Users\admin\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/admin/DS/Rugby/API/RLstat.pyw", line 794, in
window = MainWindow(application)
File "C:/Users/admin/DS/Rugby/API/RLstat.pyw", line 275, in init
self.teams_stats_sheet.font(('Calibri', 9, 'normal'))
File "C:\Users\admin\Anaconda3\lib\site-packages\tksheet_tksheet.py", line 1357, in font
self.MT.font(newfont)
File "C:\Users\admin\Anaconda3\lib\site-packages\tksheet_tksheet_main_table.py", line 2279, in font
raise ValueError("Parameter must be three-tuple")
ValueError: Parameter must be three-tuple
Cause:
In MainTable.font()
method there is a condition if len(newfont) > 2:
, so that expected length of the newfont (3) raises an error.
Solution:
Change if len(newfont) > 2:
by if len(newfont) != 3:
I also would like to propose to change:
if (
not isinstance(newfont, tuple) or
not isinstance(newfont[0], str) or
not isinstance(newfont[1], int)
):
by
if (
not isinstance(newfont, tuple) or
len(newfont) < 2 or
not isinstance(newfont[0], str) or
not isinstance(newfont[1], int)
):
tksheet/tksheet/_tksheet_main_table.py
Line 4223 in 8333d6a
Good Day,
A little fix here that doesn't need comment :)
self.text_editor.textedit.bind("<Option-Return>", self.text_editor_newline_binding)
Best Regards
tksheet/tksheet/_tksheet_main_table.py
Line 2518 in b9c27d9
Good Day,
Please see the attached line code.
I want to display a sheet of 5 columns, hence I call: display_columns([0,1,2,3,4])
If I call MainTable.insert_col_rc with anything selected == True, I expect that it adds a column at the last position and displays it if I am not wrong.
But at this line code and the one after, it seems to hide the last column and add 2 columns:
display_columns() == [0,1,2,3,5,6]
Let me know if I am wrong, this line code shifts by one the positions.
Best Regards and Thank you for your amazing work
Thank you for making this! I just had a question, If I wanted to disable the right click menu and add a custom button to delete the entire row.
How will I proceed?
I am quite new to tkinter.
Hello,
Thanks for your hard work,
I'd like to know how to get the last row in sheet / or the total number of available rows in sheet
without looping through the whole sheet,
Good afternoon!
Is it possible to fill the table using the parallel filling method. I need to display large arrays of tables from a database. Treeview Tkinter does not allow working with streams. Filling in the table takes 40 minutes.
First of all, thanks for this amazing tool 👍
Is there an easy solution to having an image rather than text in a cell?
Is there an easy solution to have a tooltip binding on a cell?
Thanks in advance
@ragardner
Hi,
(I wanted to send you a message before posting my issue, but I didn't find how) : Yours module look really great !
I begin to use it and found a little thing which looks like a bug in the demo part ...
My issue :
Demo locks on the 2nd mainloop() call in demo part of the _tksheet.py file.
I suppose that it is because one of the mainloop() calls should be removed,
and I suggest to remove the 2nd one.
As I am quite new on github, I would like to create a pull request for that in the next few days if you agree with that, so I propose to fix this quite simple issue by myself.
Best regards,
Herve
sheet.header_font('Arial',14,'normal')
TypeError: header_font() takes from 1 to 2 positional arguments but 4 were given
The right click bindings might not work properly for Mac OS
The ReadMe Features section contains the following bullet:
Could you elaborate on this? May cells may contain arbitrary Python objects?
Also, how can sheet contents be saved to a file?
Thanks for sharing your software.
/jim
Hello @ragardner
Thanks for your effort on creating this amazing library.
Can we show the cell's value in a tooltip or sth like that when we hover on it ?
I read the DOCUMENTATION.md and didn't found any method to support this (I'm sorry if I missed)
Thanks and best regards,
longk15t
Hi,
For information, I notice that binding to mouse wheel does not work on Linux, because for mouse wheel:
<MouseWheel>
is being used<Button-4>
and <Button-5>
is being usedI added in your code, bellow binding <MouseWheel>
:
self.bind("<MouseWheel>", self.mousewheel)
self.bind("<Button-4>", self.mousewheel)
self.bind("<Button-5>", self.mousewheel)
self.unbind("<MouseWheel>")
self.unbind("<Button-4>")
self.unbind("<Button-5>")
And it is working as expected on Linux
Have a nice day
Should only measure width and height of displayed upon edit cell, not entire column/row involved
Hello @ragardner, have a good day.
I have a question, can we resize the sheet widget when I resize the main window so I can see horizontal + vertical scrollbar of the sheet ?
Currently, this is what I get when I downsize the main window
Thanks and best regards,
longk15t
First of all, I would like to thank you for this amazing library. It's amazing. Period. (It can render 1114111 columns with no problem, albeit 2 rows)
There seems to be a bug in where this is a blank column to the left of the first user-defined column. Using the scrollbar even though it isn't "active" (grayed out) when the window is bigger than the table width-wise will cause an extra column to appear.
Here is a zip of the video: (Sorry for the inconvenience of having to download and extract a file)
tksheet bug.zip
Hi.
First of all, I really what you have made here, and using it for a project. By far the best solution I have found to display data in a table for tkinter.
But I have a problem with updating a given number in the table. I have a database, where information about a set products are stored. When one products is updated in the database, a number in the table should be updated, and display the updated number. But this does not happen. The number is updated in the database, and I can see, via the terminal, that the number is updated, but it is not disaplayed. If I stop the program and then start it again, the updated number is displayed. To update cells, I used sheet.set_cell_data(?, ?, ?). Do you have any ideas on what I could do to solve this.
In advance thanks.
Kind regards, 123inge.
Love and kindness to you =)
PS: I've added this in my local fork, but I think I wrote bad code...
Good Day,
tksheet/tksheet/_tksheet_main_table.py
Lines 2222 to 2232 in b1e277d
I was investing on the handling of the touchpad scrolling because it is not working on Mac but on Windows.
I have noticed the command for ctrl-c and ctrl-v are bound to Windows ctrl key and not Mac cmd key; So I guess your library is developped for Windows.
I have investigated : https://stackoverflow.com/questions/17355902/tkinter-binding-mousewheel-to-scrollbar
Platform differences:
- On Windows, you bind to and you need to divide event.delta by 120 (or some other factor depending on how fast you want the scroll)
- on OSX, you bind to and you need to use event.delta without modification
- on X11 systems you need to bind to and , and you need to divide event.delta by 120 (or some other factor depending on how fast you want to scroll)
Here is my fix:
self.bind("<MouseWheel>", self.mousewheel)
def mousewheel(self, event=None):
if event.state==1:
if event.num == 5 or event.delta == -120 or event.delta == -1:
self.MT.xview_scroll(1, "units")
self.CH.xview_scroll(1, "units")
if event.num == 4 or event.delta == 120 or event.delta == 1:
if self.MT.canvasx(0) <= 0:
return
self.MT.xview_scroll(-1, "units")
self.CH.xview_scroll(-1, "units")
self.MT.main_table_redraw_grid_and_text(redraw_row_index = True)
else:
if event.num == 5 or event.delta == -120 or event.delta == -1:
self.MT.yview_scroll(1, "units")
self.RI.yview_scroll(1, "units")
if event.num == 4 or event.delta == 120 or event.delta == 1:
if self.MT.canvasy(0) <= 0:
return
self.MT.yview_scroll(-1, "units")
self.RI.yview_scroll(-1, "units")
self.MT.main_table_redraw_grid_and_text(redraw_row_index = True)
event.state==1 means shift is pressed during scroll so it corresponds to horizontal scrolling.
You can also do self.bind("<Shift-MouseWheel>", self.touchpad_events)
The fix is at the Sheet Class level, so need to remove self.MT
in my application I don't have all the info to go onto the sheet at the time I create the sheet, instead I am populating it on the fly as my results become available (anywhere from 30 seconds to 15 minutes to get all rows)
unfortunately any rows added are not visible initially, it appears that there is no trigger to re render. this means that if I scroll after adding a row it becomes visible.
I think the best way to solve this would be to add a member variable to the Sheet class and a new handler:
class Sheet:
__init__(...):
self.after_insert_id = None
after_insert(self):
self.refresh()
self.after_insert_id = None
then for each type of insert handler:
insert_row(self, ...):
...
if self.after_insert_id is None:
self.after_insert_id = self.after_idle(self.after_insert)
this way no time is wasted updating the display while you're actively adding things to the sheet, but as soon as we're done a refresh is triggered
Thanks for creating this repository. It was just what I needed for a project I was working on.
I ran into a problem when attempting to delete cells using the version on the master branch. The issue came from (_tksheet_main_table.py) at line 628. The original code was
for r1, c1, r2, c2 in boxes:
which had an issue because boxes was defined as [((10,0,11,1),"cells")] so the first list element only saw 2 values to unpack. I changed line 628 (and 649 because it looked like it would have the same problem) to
for (r1, c1, r2, c2),_ in boxes:
which seemed to fix the issue.
I was able to recreate the problem with the following code:
import tkinter as tk
import tksheet
top = tk.Tk()
sheet = tksheet.Sheet(top)
sheet.pack()
sheet.set_sheet_data([[f"{ri} : {ci}" for ci in range(4)] for ri in range(10)])
sheet.enable_bindings(("single_select",
"row_select",
"column_width_resize",
"arrowkeys",
"right_click_popup_menu",
"rc_select",
"rc_insert_row",
"rc_delete_row",
"copy",
"cut",
"paste",
"delete",
"undo",
"edit_cell"))
top.mainloop()
Have a great day. Thanks for providing a great tool.
Lee
Hello
I would like to know if is this possible to trigger cell edit without pressing double left click,
I already tried event_generate(""), but it gives me an error "tkinter.TclError: Double or Triple modifier not allowed".
Regards.
I have the following code:
def vChanged(self):
print("--- Something Changed ---")
self.inData = [("Keith",), ("Sue",)]
f = False
if f:
self.sheet.data_reference(self.inData)
self.sheet.set_sheet_data([self.inData])
self.sheet.refresh()
else:
self.sheet = ts.Sheet(self.fileTab, data=self.inData, headers=[
"File Name"], set_all_heights_and_widths=True, width=300, height=700)
self.sheet.grid(row=2, column=0, columnspan=6)
If the variable f is False - The table updates with the new data but probably that is not the correct way to refresh. If the variable f is True the table does not update correctly - Note: I initially create the table using the the last two lines in the code above.
Great tool -- Keep up the good work
Thanks for your support
Redraw is delayed and no text or lines are visible in between redraws, will fix in next version
Hi, how can I get information from a table?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.