Search code examples
pythontkintertkinter-text

Tkinter: Issue with height/width scaling in tk.Text widget


I cannot seem to get the scroll on this text to work. The text will scroll to a certain extent, but then not appear afterwards. I believe that the height of the text widget is not what I want. For instance, the image below shows only about a half of what the actual result is for 遺伝子 (which I can find out by attempting to drag from a piece of text in the middle of the frame to the bottom). The width also is not the same size of the frame I would like it to be: the number 23 was just something that appeared to work.

If I do

txt = tk.Text(self.SEARCH_RESULTS_TEXT_FRAME,width=self.SEARCH_RESULTS_FRAME_WIDTH,height=20,background='#d9d9d9',relief=RIDGE)

... the width becomes much too large. I would have thought that it would only take up the size of the frame, which is 240.

Note the SEARCH_RESULTS_TEXT_FRAME is the frame in red.

Relevant code:

    #search text frame
    self.SEARCH_RESULTS_FRAME_HEIGHT = 240 #240
    self.SEARCH_RESULTS_FRAME_WIDTH = self.TITLE_FRAME_WIDTH - 23
    self.SEARCH_RESULTS_TEXT_FRAME = Frame(self.SEARCH_RESULTS_FRAME,height=self.SEARCH_RESULTS_FRAME_HEIGHT,width=self.SEARCH_RESULTS_FRAME_WIDTH)
    self.SEARCH_RESULTS_TEXT_FRAME.place(x=10,y=10,anchor = NW)
    self.SEARCH_RESULTS_TEXT_FRAME.config(background ="#adadad")

def print_dict_to_frame(self,results_list):
    txt = tk.Text(self.SEARCH_RESULTS_TEXT_FRAME,width=34,height=20,background='#d9d9d9',relief=RIDGE)
    txt.place(x=0,y=0)
    txt.tag_configure('header',justify = 'center',font=("Meiryo",12,'bold'))
    txt.tag_configure('entry',font=('Meiryo',8))
    for r_list in results_list:
        header = r_list[0]
        entry = r_list[1]
        txt.insert(tk.END, "{}\n".format(header),'header')
        for single_result in entry:
            txt.insert(tk.END,single_result+"\n",'entry')
    txt.configure(state=DISABLED)

Relevant image of the frame. Note that it is behind the text entry (in red)

How can I get the text widget to only take up the width of the frame and the height of the frame, allowing for scrolling?


Solution

  • If I do txt = tk.Text(self.SEARCH_RESULTS_TEXT_FRAME,width=self.SEARCH_RESULTS_FRAME_WIDTH,height=20,background='#d9d9d9',relief=RIDGE) ... the width becomes much too large. I would have thought that it would only take up the size of the frame, which is 240.

    The width option specifies a width in the number of characters, not pixels. If you use the value 240, the width will be 240 multiplied times the width of an average character in the font you are using.

    How can I get the text widget to only take up the width of the frame and the height of the frame, allowing for scrolling?

    Give the text widget a width and height of 1, and then let the geometry manager (pack, place, or grid) be responsible for stretching it to fit the frame.

    Since you're using place, you can use the relwidth and relheight options to make it the full size of the frame:

    txt.place(x=0,y=0, anchor="nw", relwidth=1.0, relheight=1.0)
    

    Personally, I recommend using pack or grid in almost all cases. It's much easier to create a responsive UI with them than it is with place.