Skip to content

Alignment of special UTF-8 characters on labels #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
matheuskknd opened this issue May 2, 2025 · 5 comments
Open

Alignment of special UTF-8 characters on labels #292

matheuskknd opened this issue May 2, 2025 · 5 comments

Comments

@matheuskknd
Copy link

Hello again, how are you doing?

I'm not sure if I should open an issue since I basically have a question.

It turns out that we are trying to add special UTF-8 characters to the labels as in the example below, but visually the text sometimes becomes misaligned as you can see in the print. I would like to know if there is any way to make the special characters align one below the other and also to make the texts aligned to the left between the labels.

Image

Python 3.8.12 example:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import weakref
from tkinter import messagebox, simpledialog
from typing import Any, Callable, Literal, cast

import customtkinter as ctk
import tksheet


class TableFrame(ctk.CTkFrame):

	def __init__(self, master: Any, **kwargs: Any) -> None:
		super().__init__(master, **kwargs)

		# Creating the spreadsheet as an attribute
		self.sheet: tksheet.Sheet = tksheet.Sheet(
			self,
			headers=["A", "B"],
			data=[['1', '2'], ['3', '4']],
		)
		self.sheet.pack(expand=True, fill="both")
		self.sheet.enable_bindings("all")

		# Creating a highlighted readonly span
		span: tksheet.Span = self.sheet.span(0, 1, 2, 2)
		span.highlight(bg="green", fg="black", redraw=False)
		span.readonly(True)

		# Labels translation
		self.sheet.set_options(
			copy_label="🗐 Copy",
			paste_label="📋 Paste",
			edit_cell_label="✏️ Edit",
			delete_label="🗑️ Delete",
			cut_label="✄ Cut",
			sort_rows_label="⬇ Sort Asc.",
			sort_rows_reverse_label="⬆ Sort Desc.",
			delete_rows_label="🗑️ Delete row(s)",
			insert_rows_above_label="➕ Add 1 row above",
			insert_rows_below_label="➕ Add 1 row bellow",
			insert_row_label="➕ Insert 1 row",
			clear_contents_label="✖️ Clear",
			copy_contents_label="🗐 Copy",
			cut_contents_label="✄ Cut",
			undo_label="⮌ Undo",
			select_all_label="⤫ Select All",
		)

		# Allows user to insert or add N rows in the sheet
		self.sheet.popup_menu_add_command(
			label="➕ Insert N row(s)",
			func=self.__create_insert_or_add_rows_command("INSERT", title="Insert row(s)",
																										button_label="Insert"),
			table_menu=False,
			index_menu=False,
			header_menu=False,
			empty_space_menu=True,
		)

		self.sheet.popup_menu_add_command(
			label="➕ Insert N row(s) above",
			func=self.__create_insert_or_add_rows_command("ADD_ABOVE", title="Add row(s) above",
																										button_label="Add above"),
			table_menu=False,
			index_menu=True,
			header_menu=False,
			empty_space_menu=False,
		)

		self.sheet.popup_menu_add_command(
			label="➕ Insert N row(s) bellow",
			func=self.__create_insert_or_add_rows_command("ADD_BELLOW", title="Add row(s) bellow",
																										button_label="Add bellow"),
			table_menu=False,
			index_menu=True,
			header_menu=False,
			empty_space_menu=False,
		)

	def __create_insert_or_add_rows_command(self, type_: Literal["ADD_ABOVE", "ADD_BELLOW", "INSERT"],
																					*, title: str, button_label: str) -> Callable[[], None]:
		w_sheet: tksheet.Sheet = weakref.proxy(self.sheet)

		def insert_or_add_rows_command() -> None:
			idx: int | None = None
			if type_.startswith("ADD"):
				selected: set[str] = cast(set[str], w_sheet.get_selected_rows())
				idx = int(next(iter(selected))) + int(type_ == "ADD_BELLOW")

			while True:
				text: str | None = simpledialog.askstring(title, button_label)
				if not text:
					return

				try:
					num_rows: int = int(text)
					if num_rows > 0:
						w_sheet.insert_rows(rows=num_rows, idx=idx, tree=False, redraw=True)
					return

				except Exception as e:
					messagebox.showwarning(f"Invalid number", str(e), parent=w_sheet)

		return insert_or_add_rows_command


def main():
	ctk.set_appearance_mode("light")
	ctk.set_default_color_theme("blue")

	root = ctk.CTk()
	root.geometry("800x400")
	root.title("customtkinter + tksheet")

	tabela = TableFrame(root)
	tabela.pack(expand=True, fill="both", padx=10, pady=10)

	root.mainloop()


if __name__ == "__main__":
	main()

Best regards

@matheuskknd
Copy link
Author

matheuskknd commented May 2, 2025

Also, I searched the documentation but wasn't abble to find anything about remove certain labels/commands from certain cells. We were trying to remove the edit commands for cell also marked as readonly, sinse these commands will have no effect on them. Is there a way to do this today?

I understand that, if it still have to be implemented, then it might be easier to just make the sheet.popup_menu_add_command accept a new parameter, let's say when_readonly which defaults to "True" for backward compatibility. And then tksheet handles the items to show on the right-click for readonly cells, headers or row_indexes. What do you think?

NOTE: this last request is different from the one discussed on #281, here were talking about right-click labels on specific cells on the table, more specifically the ones marked as readonly.

ragardner added a commit that referenced this issue May 3, 2025
ragardner added a commit that referenced this issue May 3, 2025
ragardner added a commit that referenced this issue May 3, 2025
@ragardner
Copy link
Owner

Hello,

Thanks for your thoughtful questions,

I don't know of any way to align special characters like the icon ones you've shown above except perhaps to use a monospace font. I am however not sure if this would be satisfactory in all cases, I think the best approach would be to use images so I made some changes to that effect.

The main changes I've made are numbered below:

  1. To address the icons and alignment in the menus I decided to add the capability to have images in menu entries added using popup_menu_add_command.
  • The new function looks like this:
popup_menu_add_command(
        label: str,
        func: Callable,
        table_menu: bool = True,
        index_menu: bool = True,
        header_menu: bool = True,
        empty_space_menu: bool = True,
        image: tk.PhotoImage | Literal[""] = "",
        compound: Literal["top", "bottom", "left", "right", "none"] | None = None,
        accelerator: str | None = None,
    ) -> Sheet
  • A drawback to this approach - the menu entries without images do not get the left hand padding that entries with images have.
  • There also seems to be a bug in tkinter, at least for me - I can't seem to find info on this, where disabling a menu item makes the image turn into a pixelated white and gray square. So I've had to remove the images of disabled menu entries, unfortunately also removing their padding in the process.
  1. I also added some changeable default free use icons to tksheet for its built in menu. You can change these icons using set_options(), I updated the documentation. This function will allow you to do it.
  1. I added undo and redo to the built in menus, should only be visible if they're enabled.
  2. To address your query about disabling menu items, especially for readonly cells:
  • I made it the default that the Edit menu entry is disabled if the currently selected cell is readonly.
  • The undo/redo menu entries for table menus should also enable/disable appropriately.
  • I am open to considering adjusting this behavior or extending it perhaps with your suggestion of adding a parameter if you think it necessary.

Kind regards

@matheuskknd
Copy link
Author

Hello! How are you doing?

First of all, thank you very much for your quick response. I have been working tirelessly to finalize the integration of tksheet in my project. Now practically all of our functionalities use it, whether for batch data entry or for displaying reports. Soon we will also use tksheet's TreeView mode to implement access management and even configuration management functionalities.

The new feature with the window in light mode looks very nice, excellent work:

Image

However, in dark mode the disabled items are quite blurry. Could you take a look, please?

Image

Sample python 3.12.8 code:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import weakref
from tkinter import messagebox, simpledialog
from typing import Any, Callable, Literal, cast

import customtkinter as ctk
import tksheet


class TableFrame(ctk.CTkFrame):

	def __init__(self, master: Any, **kwargs: Any) -> None:
		super().__init__(master, **kwargs)

		# Creating the spreadsheet as an attribute
		self.sheet: tksheet.Sheet = tksheet.Sheet(
			self,
			headers=["A", "B"],
			data=[['1', '2'], ['3', '4']],
			### Theme
			theme="dark green",
			# theme="light green",
		)
		self.sheet.pack(expand=True, fill="both")
		self.sheet.enable_bindings("all")

		# Creating a highlighted readonly span
		span: tksheet.Span = self.sheet.span(0, 1, 2, 2)
		span.highlight(bg="green", fg="black", redraw=False)
		span.readonly(True)

		# Labels translation
		self.sheet.set_options(
			copy_label="Copy",
			paste_label="Paste",
			edit_cell_label="Edit",
			delete_label="Delete",
			cut_label="Cut",
			sort_rows_label="Sort Asc.",
			sort_rows_reverse_label="Sort Desc.",
			delete_rows_label="Delete row(s)",
			insert_rows_above_label="Add 1 row above",
			insert_rows_below_label="Add 1 row bellow",
			insert_row_label="Insert 1 row",
			clear_contents_label="Clear",
			copy_contents_label="Copy",
			cut_contents_label="Cut",
			undo_label="Undo",
			select_all_label="Select All",
		)


def main():
	ctk.set_appearance_mode("light")
	ctk.set_default_color_theme("blue")

	root = ctk.CTk()
	root.geometry("800x400")
	root.title("customtkinter + tksheet")

	tabela = TableFrame(root)
	tabela.pack(expand=True, fill="both", padx=10, pady=10)

	root.mainloop()


if __name__ == "__main__":
	main()

Best regards

@ragardner
Copy link
Owner

ragardner commented May 20, 2025

Hello,

Thanks for letting me know how you're making use of tksheet! It's nice to hear people are finding it useful 😃

About the blurring issue with the menu items in dark colors...

It seems like disabled menu items have issues on dark backgrounds with some operating systems or fonts (i'm not sure which) regardless of what I try to do about it.

I had to make it so that the menu items are built on the fly upon a right click event so that disabled items, such as edit, undo or redo are excluded if they are not necessary.

This change is in 7.5.7

Kind regards

@matheuskknd
Copy link
Author

Thank you very much for the reply and the new version, @ragardner!

Hiding disabled labels is actually better, and it also solves some issues.

The only thing I think is still missing, is to hide Cut, Paste and Delete labels from read-only cells.

Image

Image

Images from the code of last example above.

Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants