0

I am creating a game similar to bitlife in Tkinter. Although I have run into a problem. If you recall from bitlife, or any texting platform, you create text, then all the previously created text goes up. This existing text will then go into a scrollable frame (which I have already achieved). I am not asking for the straight up code, just any methods or ideas on how to make the previously created text go up. Thanks!

Ali
  • 33
  • 5
  • If you keep adding text to a text box, the text at the start of the box will appear to move up the box and eventually off the top. Perhaps you can be a bit more specific about why the standard behaviour of a text box isn't what you want. – scotty3785 Jan 12 '21 at 15:56
  • I forgot to mention, I am using the Tkinter Canvas. Whenever I created text, the previously created text would stay in place and the new text would be created over it. I am not sure if creating a text box on Canvas would work. – Ali Jan 12 '21 at 15:58
  • So you want a scrollable canvas that kind of behaves like a messaging app on a phone? – scotty3785 Jan 12 '21 at 16:00
  • Yes, that is exactly what I am trying to achieve! – Ali Jan 12 '21 at 16:02
  • @Ali check out the ScrollBar widget. [Here](https://stackoverflow.com/questions/7727804/tkinter-using-scrollbars-on-a-canvas) – JacksonPro Jan 12 '21 at 16:14
  • Thank you so much, it is great, although I am not sure how to implement the text feature in my original question. – Ali Jan 12 '21 at 16:17

1 Answers1

0

Not complete but I'm out of time.

Hacked together to show you how to add items to a canvas that very loosely looks like a text message application. Not pretty at all but I only had 10 mins

import tkinter as tk

class Message(tk.Frame):
    def __init__(self,parent,name,text):
        super().__init__(parent,width=250)
        self.lblName = tk.Label(self, text=name, font=('Arial','10'))
        self.lblName.grid(row=0,column=0)
        self.lblText = tk.Message(self, text=text, font=('Arial','14'))
        self.lblText.grid(row=1,column=1)


class MessageFrame(tk.Frame):
    def __init__(self,parent):
        super().__init__(parent)
        # Add a canvas in that frame
        self.canvas = tk.Canvas(self, bg="yellow")
        self.canvas.grid(row=0, column=0, sticky="news")

        # Link a scrollbar to the canvas
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.vsb.grid(row=0, column=1, sticky='ns')
        self.canvas.configure(yscrollcommand=self.vsb.set)

        # Create a frame to contain the buttons
        self.frame_buttons = tk.Frame(self.canvas, bg="blue")
        self.canvas.create_window((0, 0), window=self.frame_buttons, anchor='nw')

        self.messages = []
        self.msgItems = []

    def add_message(self, sender, text):
        self.messages.append({'name':sender,'text':text})
        self.refresh_msg_list()

    def refresh_msg_list(self):
        if self.msgItems:
            for item in self.msgItems:
                item.destroy()
            self.msgItems = []
        
        for idx,msg in enumerate(self.messages):
            newItem = Message(self.frame_buttons, msg['name'], msg['text'])
            #newItem = tk.Button(self.frame_buttons, text=task['task'])
            newItem.grid(row=idx,column=0,sticky='news',pady=10)
            self.msgItems.append(newItem)

        # Update buttons frames idle tasks to let tkinter calculate buttons sizes
        self.frame_buttons.update_idletasks()

        # Resize the canvas frame to fit 5 messages
        first5rows_height = max([task.winfo_height() for task in self.msgItems]) * 5
        item_width = max([task.winfo_width() for task in self.msgItems])
        ##frame_canvas.config(width=first5columns_width + vsb.winfo_width(),
        ##                    height=first5rows_height)
        self.config(height=first5rows_height,width=item_width+self.vsb.winfo_width())

        # Set the canvas scrolling region
        self.canvas.config(scrollregion=self.canvas.bbox("all"))


def add_new_item():
    pass

def add_first_item():
    msg.add_message('SenderName','How are you?')
    msg.add_message('SenderName','How are you?')
    msg.add_message('SenderName','How are you?')
    msg.add_message('SenderName','How are you?')
    msg.add_message('SenderName','How are you?')

root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)

frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')

# Create a frame for the canvas with non-zero row&column weights
msg = MessageFrame(frame_main)
msg.grid(row=2, column=0, pady=(5, 0), sticky='nw')
msg.grid_rowconfigure(0, weight=1)
msg.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow 5-by-5 buttons resizing later
msg.grid_propagate(False)

root.after_idle(add_first_item)

root.after(2000,add_new_item)

root.mainloop()
scotty3785
  • 6,763
  • 1
  • 25
  • 35