customtkinter - Typing speed test with Python - custom Tkinter textbox scroll-up mechanism to keep focus on first line of text -

I am building a typing speed test with Python, and I created two CTK widgets, a CTkTextbox, and a CTkEn

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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信