I am building a typing speed test with Python, and I created two CTK widgets, a CTkTextbox, and a CTkEntry. I start the app by loading a long text in the textbox, and the user must type all of the text's words inside the Entry widget, trying to replicate the text as quickly and accurate as possible. Screen shot from the app screen
The app provides feedback to the user by tagging the words in the textbox with different colors, and highlighting the word that user is typing with a green background. The logic to control the tagging is based on character and word counts - I created an index for each (col_index and word_index) and used the space character count to link the words being typed by the user in the Entry widget to the words displayed in the textbox (when user types space, app assumes word is completed and tagging on textbox moves to the following word).
I want the text box to scroll up every time the user completes typing the last word in the first line - that way his focus should always on the first line of text, only. I explain my solution below, and I am open to any ideas to solve the problem.
I initiate the app by grabbing the sample text and adding up char count and pixels count. Every time the pixels sum exceeds the widget window size, I append the position of the last space character into a list, and then reset the pixel count adjusting for the size of the text which breached the window size. The objective is to use the reference positions stored in the list to trigger a scroll up command on the textbox widget every time the words being typed by the user on the Entry widget reach the coordinates stored in the list.
How does custom tkinter converts tag indexes into texbox screen coordinates?
PS: I process the text format so it is a single long string of words and characters with a single space character between them
Relevant Code Snippets:
self.sample_text_view = CTkTextbox(
self.container,
width=700,
height=100,)
self.user_text_entry = CTkEntry(master=self.container,
width=700,
height=40,)
def creates_scroll_list(self):
"""Finds the index of the last visible character on the first line of the textbox."""
# Get the width of the textbox in pixels
textbox_width = self.sample_text_view.winfo_width()
# Get the text content
text = self.sample_text_view.get("0.0", "1.end")
# Iterates through the characters of the tex, measuring their width
# and creates a list of indexes marking the character numbers of the last words fitting inside the widget line
col_index = 0 # counts the number of characters
visual_text_pixels = 0 # adds up the characters' pixels sizes
for char in text:
self.sample_text_view.update_idletasks()
visual_text_pixels += self.sample_text_view.bbox(f"1.{col_index}")[2]
if char == ' ':
if visual_text_pixels > textbox_width: # grabs the col_index reference for scrolling and resets line pixels
visual_text_pixels -= last_space_pixels # resets pixel count for new line
self.scroll_triggers_list.append((last_space_col, last_space_pixels)) # stores the positions (index and pixel sie) of last words that fit the line
else:
last_space_col = col_index
last_space_pixels = visual_text_pixels
col_index += 1
I tried implementing a solution by using bbox() to count the words pixels and scroll-up when the sum exceeds widget width, but for some reason this is not working and the bbox() response does not match what I see on screen.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742302609a4418311.html
评论列表(0条)